MySQL:我应该为这些查询设置什么索引?
我很难弄清楚到底需要索引什么才能使我的查询尽可能高效。所使用的表有数十亿行,因此如果没有索引,它将毫无用处 我知道当我用MySQL:我应该为这些查询设置什么索引?,mysql,sql,Mysql,Sql,我很难弄清楚到底需要索引什么才能使我的查询尽可能高效。所使用的表有数十亿行,因此如果没有索引,它将毫无用处 我知道当我用搜索某物时。。。而且这些列应该一起索引,但我不明白索引在更复杂的情况下是如何应用的,比如COUNT和ORDER BY 请告诉我以下查询需要哪些索引: 问题1: SELECT word1,word2,COUNT(id) AS aaa FROM mytable WHERE (word1>0 AND word2=429907) OR (word1=429907 AND
搜索某物时。。。而且
这些列应该一起索引,但我不明白索引在更复杂的情况下是如何应用的,比如COUNT
和ORDER BY
请告诉我以下查询需要哪些索引:
问题1:
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秒(听起来很快,但我认为它并没有得到尽可能多的优化。)您应该回顾一下索引在MySQL中的使用方式 第一个查询不使用索引,因为它在两列的
where
子句中都有一个不等式。为了提高效率,您需要重写查询,并可能添加另一个索引。另外,如果id
从不为空,我认为您最好使用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)
上建立索引
如果您首先在子查询中进行聚合,然后再在外部级别进行聚合,那么这可能会更快
您的第二个查询可能由于计数(id)
而减慢。它可能正在使用分组依据
的现有索引。然后它需要从数据页获取id
。添加一个类似于mytable(word1,word2,id)
的索引,或者将代码更改为count(*)
第三个查询将受益于
mytable(word1,word2,pibn)上的索引
尝试EXPLAIN
在您的查询中,它将为您提供一些关于瓶颈位置的提示。EXPLAIN的输出是什么?总的来说,它为找到好的索引提供了很好的提示。我确实使用了EXPLAIN,但它所做的只是告诉我使用了哪个索引,而不是在每种情况下索引的效率。索引(word2
,word1
)可能有助于第一次查询(虽然我知道mySQL不一定有其他RDBMS那么好的优化器)。索引(word1
,word2
,pibn
,page
)应该有助于查询2和3。说到2,从这样的临时表切换到子查询引用(例如,from(SELECT…
)也可能有帮助。