mysql 这个统计表怎么做

mysql 这个统计表怎么做,第1张

统计信息数据库基于成本的优化器最重要的参考信息;统计信息不准确,优化器可能给出不够优化的执行计划或者是错误的执行计划。对统计信息的计算分为非持久化统计信息(实时计算)与持久化统计信息。

非持久化统计信息

统计信息没有保存在磁盘上,而是频繁的实时计算统计信息;

每次对表的访问都会重新计算其统计信息;

假设针对一张大表的频繁查询,那么每次都要重新计算统计信息,很耗费资源。

持久化统计信息

把一张表在某一时刻的统计信息值保存在磁盘上;

避免每次查询时重新计算;

如果表更新不是很频繁,或者没有达到 MySQL 必须重新计算统计信息的临界值,可直接从磁盘上获取;

即使 MySQL 服务重启,也可以快速的获取统计信息值;

统计信息的持久化可以针对全局设置也可以针对单表设置。

接下来,详细说 MySQL 统计信息如何计算,何时计算,效果评估等问题。在 MySQL Server 层来控制是否自动计算统计信息的分布,并且来决策是持久化还是非持久化。

我觉得至少有2这种解决方法:

1.修改datarecord的入库机制

既然datarecord里面有大量的数据,但是你需要的是统计出来每个Id的Value最大值,根据这一点

你在向datarecord存入数据时就应该先比较一下,只把比比某个ID的最大的value更大的数存到数据库里,

这种 *** 作其实非常简单,这样的话在datarecord里面存的数据都是截止当前每个ID的最大的value,使用的时候直接使用了,但是你要把每个ID最大的value

写入,然后要把较小的那个给删掉,这样的话,在写入数据时都要查询会影响到入库的性能。

这种机制再向前推进一步,就是在内存里维持一个MAP,名为DatarecordMap,然后再创建一个class,用datarecord表的各个字段值作为属性,

用key=ID,value=Object(Time,value,Quality),

每当有一个新的数据要存入这个MAP时,比较一下,总是把每个ID,最大的value存入MAP,这样比存入如数据库的读写性能高多了

其实你总的ID才1250个,并不算大放内存里处理效率会高很多

这种方法最大的优点是只在内存中保留每个ID最大的value值(其实是整个记录)

因此实际需要的内存并不大

代码:

public class Datarecord {

private int id

private Date time

private int Value

private int Quality=0

public Datarecord(int id,Date time,int Value){

this.id = id

this.time =time

this.Value =Value

}

<此处掠去set get方法>

}

import java.util.Date

import java.util.HashMap

import java.util.Map

import java.util.Random

public class SaveRecord {

/**

* @param args

*/

public static void main(String[] args) {

Map<Integer,Datarecord>DatarecordMap = new HashMap<Integer,Datarecord>()

Datarecord data =null

Random rand = new Random()

int id,value

int number=100000

long t1 = System.currentTimeMillis()

for(int i=1i<=numberi++){

//rand.nextInt(MAX - MIN + 1) + MIN

//模拟产生id,范围1 -- 5

id = rand.nextInt(10) + 1

//模拟产生value,范围1 --- 10000

value = rand.nextInt(100000) + 1

//System.out.println("id:"+id + " value:"+value)

if (DatarecordMap.containsKey(id)){

data = DatarecordMap.get(id)

//判断DatarecordMap 里面当前id对应的value是否被新的value小,如果小直接把这个小的覆盖掉

if (data.getValue()<value){

data = new Datarecord(id,new Date(),value)

DatarecordMap.put(id, data)

}

}else{

data = new Datarecord(id,new Date(),value)

DatarecordMap.put(id, data)

}

}

long t2 = System.currentTimeMillis()

System.out.println("产生"+number+"个数据,用时:"+(t2-t1)+"ms.")

System.out.println("输出每个id 的最大VALUE值========================")

long t3 = System.currentTimeMillis()

for(Integer key:DatarecordMap.keySet()){

System.out.println("id:"+key + " value:"+DatarecordMap.get(key).getValue())

}

long t4 = System.currentTimeMillis()

System.out.println("用时:"+(t4-t3)+"ms.")

}

测试结果:

产生100000个数据,用时:26ms.

输出每个id 的最大VALUE值========================

id:1 value:99995

id:2 value:99996

id:3 value:99994

id:4 value:99996

id:5 value:99992

id:6 value:99996

id:7 value:99993

id:8 value:99993

id:9 value:99990

id:10 value:99977

用时:1ms.

上面的代码模拟产生了100000个数据,用时26ms,数据库无论如何不到这样的性能,在第2个循环中输出每个ID的最大值,用时1ms,你在实际的应用中

可以把这个输出结果先生成一个数据文件,然后用mysql的load命令导入,时间会在不会大于1秒,其实每个ID的最大值汇总在一起并不多,在你的应用中有

1250个,用load命令导入的话,1秒不到就轻松搞定

2.优化数据库

其实写了上面的方法,我已经不想写这个了,这个无论咋优化都打不到第一种方法的性能

如果你觉得第一种方法datarecord表似乎已经没用了,但是又需要要把数据持久化到datarecord表里,可以定时把DatarecordMap表的数据取出,全部写到datarecord表里

但是要先清空这个表的数据,这样的话在某个周期内,datarecord表的数据总是每个ID的最大值


欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/7644187.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-08
下一篇 2023-04-08

发表评论

登录后才能评论

评论列表(0条)

保存