通过与mysql中的where条件一起使用来优化组

时间:2014-02-04 18:03:04

标签: mysql sql database myisam database-optimization

我有一个大约有8M行和35列(整体大小为1G)的表。这用于涉及多级group by条件的报告。这是一个这样的查询。

explain select min(a), max(a), avg(a), sum(b) from test where (c=2 or c=20 or c=18 or c=21 or c=12) and d>='2013-01-01' and d <= '2013-12-01' group by c,e;

*************************** 1. row ***************************
       id: 1
select_type: SIMPLE
    table: test
     type: range
possible_keys: PRIMARY
      key: PRIMARY
  key_len: 7
      ref: NULL
     rows: 154911
    Extra: Using where; Using temporary; Using filesort
1 row in set (0.00 sec)

这需要大约1.8秒才能执行。主键位于c,d上,用于评估where子句。具有相同where条件且没有group by的count(*)查询返回大约150000行。因此,在实际查询中扫描的行也可以。但是,没有一个索引被用于分组结果。我已尝试在cc,e上添加索引。

我的问题是,在应用条件并且结果集在tmp表中时,可以使用另一个索引进行排序/分组。

我为tmp_table_size分配了足够的内存。所以,tmp表肯定不会进入磁盘。该表格正在使用MyISAM

3 个答案:

答案 0 :(得分:0)

如果使用(c,d,e,a,b)制作索引,则性能会更快。这将是一个覆盖索引,并且表扫描将不会像现在那样完成。

另外,我只是好奇,你能给我一些关于你正在使用的effective_month功能的指示吗?

另外,一个重要的是索引大小。每个存储引擎定义每个表的最大索引数和最大索引长度。您可以阅读更多相关信息here。在你的情况下,这不会是一个问题因为你正在处理我假设日期和数字。只是插入的速度会慢一些。

答案 1 :(得分:0)

覆盖索引可能有所帮助。假设这是您的查询:

select min(a), max(a), avg(a), sum(b)
from test
where (c=2 or c=20 or c=18 or c=21 or c=12) and
      d >= '2013-01-01' and d <= '2013-12-01'
group by c, e;

覆盖指数为test(c, d, e, a, b)

然而,很难摆脱MySQL聚合中的文件排序。

答案 2 :(得分:0)

在任何SQL中,出于任何原因,如果只在一个表上执行多次扫描,我们可以为其中任何一个使用一个索引,但不能同时使用两个。

EX:您的查询需要

  1. 一次扫描处理where子句数据。(INDEX1:c上的索引,d很有用)
  2. 一次扫描,按操作对组进行排序。(INDEX2:c,e上的索引很有用)
  3. 如果结果集中的行数更多,则最好添加INDEX2,以便快速排序。 如果结果集中的行数较少,则最好添加INDEX1,以便快速处理where子句。