Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:我应该为这些查询设置什么索引?_Mysql_Sql - Fatal编程技术网

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…
)也可能有帮助。