1

我很难弄清楚需要索引什么才能使我的查询尽可能高效。使用的表有数十亿行,所以没有索引它是无用的。

我知道当我搜索WHERE ... AND这些列应该一起索引的东西时,但我不明白索引如何应用于更复杂的情况,比如COUNTORDER BY

请有人告诉我以下查询需要哪些索引:

查询一:

SELECT word1,word2,COUNT(id) AS aaa
  FROM mytable
  WHERE (word1>0 AND word2=429907) OR (word1=429907 AND word2>0)
  GROUP BY word1,word2
  ORDER BY aaa DESC LIMIT 20;

查询 2:

CREATE TEMPORARY TABLE temptbl (
  pibn INT UNSIGNED NOT NULL, page SMALLINT UNSIGNED NOT NULL)
  ENGINE=MEMORY;
INSERT INTO temptbl (
  SELECT DISTINCT pibn,page FROM mytable
  WHERE word1=429907 AND word2=0);
ALTER TABLE temptbl ADD PRIMARY KEY (pibn,page);
SELECT word1,word2,COUNT(id) AS aaa
  FROM mytable a
  INNER JOIN temptbl b
  ON a.pibn=b.pibn AND a.page=b.page
  GROUP BY word1,word2 ORDER BY aaa DESC LIMIT 10;
DROP TABLE temptbl;

查询 3:

SELECT pibn,COUNT(*) AS aaa
  FROM mytable
  WHERE word1=429907 AND word2=12322
  GROUP BY pibn ORDER BY aaa DESC LIMIT 25

目前的指标是:

id
pibn,page
word1,word2,origyear,cat

就目前而言(使用当前索引)查询 1 需要 13 秒,查询 2 需要 35 秒,查询 3 需要 0.1 秒(这听起来很快,但我认为它没有得到尽可能多的优化。)

4

1 回答 1

0

您应该在此处查看MySQL 中如何使用索引。

您的第一个查询不使用索引,因为它where在两列的子句中都有不等式。为了提高效率,您需要重写查询并可能添加另一个索引。此外,如果id从不为 NULL,我认为您最好使用count(*). 这将允许查询仅通过查询扫描完成。

重写后的查询如下所示:

select  word1, word2, count(*)
from ((select word1, word2
       from mytable
       where word1>0 AND word2=429907
      ) union all
      (((select word1, word2
       from mytable
       where word2>0 AND word1=429907
      )
     ) t
 group by word1, word2

mytable(word2, word1)出于性能原因,此查询需要索引。

如果您先在子查询中进行聚合,然后再在外部级别进行聚合,这可能会更快。

您的第二个查询可能会因count(id). 它可能正在使用group by. 然后它需要id从数据页中获取。要么添加一个类似的索引,mytable(word1, word2, id)要么只是将代码更改为count(*).

第三个查询将受益于mytable(word1, word2, pibn).

于 2013-04-15T15:58:47.593 回答