使用WHERE和GROUP BY进行查询的最有效索引?

时间:2012-01-25 01:13:06

标签: mysql sql optimization indexing query-optimization

我有一个包含大约700万行的表,我不断运行这类查询:

SELECT 
      MyField, 
      COUNT(*) 
   FROM 
      MyTable 
   WHERE 
          MyField2='ConstantValue' 
      AND MyField NOT IN ( SELECT Field 
                              FROM AnotherTable) 
      AND Timestamp >= [ArbitraryTimestamp] 
   GROUP BY 
      MyField;

以上领域的基数:

  • MyField =大约40,000个不同的值。
  • 时间戳=大多数是不同的,因此大约有700万个不同的值。
  • MyField2 = 2个不同的值。
  • Field FROM AnotherTable =约50个不同的值。

正如所料,这种情况非常缓慢,使用EXPLAIN告诉我,我Using where; Using temporary; Using filesort

我想通过在此表中添加索引来提高这些查询的效率,但我不确定最好的方法是什么。

我应该在MyField上添加索引吗?和Timestamp上的索引?都?两者的综合指数?

另外,我还能做些什么来加速这些类型的查询吗?

2 个答案:

答案 0 :(得分:0)

您应首先使用MyField添加双键索引(分组依据):

CREATE INDEX MyIndex
    ON MyTable (MyField, Timestamp)

答案 1 :(得分:0)

MyField上的GROUPBY将强制MySQL创建一个临时表,这就是你在EXPLAIN中获得using temporary的原因。创建一个包含约700万行的临时表肯定是一个痛苦的查询。

要尝试的事情(在实施每个建议后,重新运行查询并检查查询时间):

  1. 向MyField添加索引
  2. 查看是否可以通过添加最大时间戳(加上最小时间戳)来限制行数
  3. 仅为MyField2和MyField3列添加索引
  4. 如果您的查询响应仍然很慢,请尝试在所有三列(Myfield,MyField2和MyField3)中添加复合索引
  5. 如果以上都不能立即为您提供帮助,请查看此post,了解如何使用子查询来获取计数,这样可以完全避免使用GROUP BY。