这主要是一个数据统计的web页面,展现统计结果。由于当时需求很紧,要求尽快能出来查询结果就行,而且是说以后会重新对这部分功能进行规划再开发。所以也没有考虑任何性能相关,劈哩啪啦的一天把很多数据统计的功能实现了。

现在,数据量已然有点规模了,但是还没有再开发的计划,目前还使用这个统计程序,但是由于有些数据量了,并且没有考虑过优化,所以目前查询速度很慢。尤其是其中有一个查询,居然耗时1分多,问题很大啊,今天抽点时间,找找问题,优化一下,主要做的工作的是改进sql语句,添加合适的索引。

存储的数据是根据用户的ID末尾的值来简单分表的,所以共有0到9一共10个表,需要遍历这10个表,然后把最后的数据相加,再处理后得到最后结果。由于需求还算比较简单,所以没有采用定时脚本去处理前几日的数据后入库保存的做法,如果采用以上做法,速度会快更多。

以下是其中的一个处理的一条sql,运行看起来耗时11.76秒。

首先做的第一步,把连接的两个表做处理,分别只提取出需要的字段,并把对a表的时间限制放到连接前。

然后,可以看到,遍历b表的行数还是很多的,所以根据需求,添加合适的对b表的限定条件,缩减b表的行数。然后再运行的时候,就能看到,只需要1秒多了。

没有写出来如何添加索引的,也就不写了,自己根据explain的结果看,需要哪些索引吧。

有一点要说的是,再对某datetime类型的列添加索引后,发现查询时没有使用索引,explain了一下,会遍历27K多条数据,使用force index再来explain下这条sql,类似: explain SELECT * from table force index(index_name) where datetime between ‘2011-03-01’ and ‘2012-03-28’ ;得到的结果是会遍历9K条数据,占上个结果的三分之一,所用时间同不用索引没啥差别,所以,可能是当数据量小到一定的比例时,索引才会被调用。

—–

2012年3月28日 PS:查询了下手册,发现了关于是否使用索引的说明

每个表的索引被查询,并且使用最好的索引,除非优化器认为使用表扫描更有效。是否使用扫描取决于是否最好的索引跨越超过30%的表。优化器更加复杂,其估计基于其它因素,例如表大小、行数和I/O块大小,因此固定比例不再决定选择使用索引还是扫描。

官方手册:http://dev.mysql.com/doc/refman/5.1/zh/optimization.html#where-optimizations