如何在sql查询中避免临时表?

时间:2013-12-07 07:26:54

标签: mysql sql performance optimization temp-tables

我正在运行查询(需要3分钟才能执行) -

SELECT c.eveDate,c.hour,SUM(c.dataVolumeDownLink)+SUM(c.dataVolumeUpLink) 
FROM cdr c 
WHERE c.evedate>='2013-10-19'
GROUP BY c.hour;

解释计划 -

id  select_type  table  type  possible_keys                 key  key_len  ref  rows      Extra                                         
1   SIMPLE       c      ALL   evedate_index,eve_hour_index                     31200000  Using where; Using temporary; Using filesort  

我正在使用桌子(Myisam) -

  

主键(id,evedate),

     

每周8个分区,带有关键evedate,

     

索引键 - 在evedate上,

     

复合指数在evedate,小时。

我已将my.ini中的mysql调整参数更改为(4GB RAM) -

  

tmp_table_size的= 200M

     

的key_buffer_size = 400M

     

read_rnd_buffer_size = 2M

但仍使用临时表和文件排序。请让我知道如何排除这一点。

编辑: 添加新的综合索引(evedate,msisdn)

我发现在一些查询中他们没有使用任何临时案例的一些更改,即使在上面的查询中我省略了group by子句,也没有使用临时表。

谢谢。

1 个答案:

答案 0 :(得分:1)

你无能为力。 MySql无法优化此查询并避免使用临时表。

根据此链接:http://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html
有两种MySql用来优化GROUP BY的方法。


第一种方法 - 松散索引扫描 - 无法用于您的查询,因为不符合此条件:

  

选择列表中使用的唯一聚合函数(如果有)是MIN()和MAX()....

您的查询包含SUM,因此MySql无法使用上述优化方法。


第二种方法 - 紧密索引扫描 - 无法用于您的查询,因为此条件不符合:

  

要使此方法起作用,对于查询中所有列的常量相等条件就足够了,这些列引用了GROUP BY键之前或之间的键部分。

您的查询仅使用范围运算符:WHERE c.evedate>='2013-10-19',WHERE子句中没有任何相等条件,因此此方法不能用于优化查询。