简体   繁体   English

MySql不与ORDER BY一起使用索引

[英]MySql doesn't use index with ORDER BY

I have a table with this structure (with 50k fields): 我有一个具有此结构的表(具有50k字段):

CREATE TABLE IF NOT EXISTS `comments` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `imageid` int(10) unsigned NOT NULL DEFAULT '0',
  `uid` bigint(20) unsigned NOT NULL DEFAULT '0',
  `content` text CHARACTER SET utf8,
  `adate` datetime DEFAULT NULL,
  `ip` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `ids` (`imageid`,`adate`) USING BTREE
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=52236 ;

I want to select data by imageid and sort it with adate so I added ( imageid , adate ) key. 我想通过imageid选择数据并用日期对其进行排序,所以我添加了( imageidadate )键。

but the explain result of this query says MuSQL still use table scan. 但是该查询的解释结果表明MuSQL仍使用表扫描。 Why?! 为什么?!

EXPLAIN SELECT   comments.*
FROM comments
WHERE comments.imageid=50
ORDER BY
comments.adate DESC LIMIT 10

result: 结果:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  comments    ref     ids     ids     4   const   203     Using where

and with this index: 并具有以下索引:

KEY `ids` (`imageid`,`adate`,`id`) USING BTREE

the result for this query: 该查询的结果:

EXPLAIN SELECT   comments.id
FROM comments
WHERE comments.imageid=50
ORDER BY
comments.adate DESC LIMIT 10

IS: IS:

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  comments    ref     ids     ids     4   const   203     Using where; Using index

You are not reading the results from explain correctly. 没有从正确解释中读取结果。

using index means that the query is index-covered - the data is read only from the index, and the actual row is not used. using index意味着查询已被索引覆盖-数据仅从索引中读取,而未使用实际行。 This is not because the index is different, but because in the second query you are selecring only the id. 这不是因为索引不同,而是因为在第二个查询中,您仅选择了id。

If MySQL does not use index for resolving the ORDER BY there would be using filesort in the explain. 如果MySQL不使用索引来解析ORDER BY则说明中将using filesort In both queries, ids key is used and MySQL does not perofrm a table scan 在这两个查询中,都使用了ids键,而MySQL 不会执行表扫描

For InnoDB create a key like this (imageid,adate,id); 对于InnoDB,创建一个这样的密钥(imageid,adate,id); order of column in index is important. 索引中列的顺序很重要。

Then try this - 然后试试这个-

EXPLAIN SELECT   comments.id
FROM comments
WHERE comments.imageid=50
ORDER BY
comments.adate DESC LIMIT 10

Let me know what is the output. 让我知道输出是什么。

Thanks for the output. 感谢您的输出。 Adding following section below. 在下面添加以下部分。

If you require more than id then try something like this 如果您需要的不仅仅是ID,请尝试这样的操作

EXPLAIN 
SELECT c1.* from comments as c1
JOIN
(
   SELECT comments.id
   FROM comments
   WHERE comments.imageid=50
   ORDER BY
   comments.adate DESC LIMIT 10
) as c2 ON (c1.id=c2.id)

But this time do not rely on Explain. 但这一次不依赖于解释。 Explain will show one row with index anyway still. 无论如何,说明仍将显示带有索引的一行。 Rather check execution time in phpmyadmin or in mysql query browser. 而是在phpmyadmin或mysql查询浏览器中检查执行时间。

Straight out of the manual: 直接脱离手册:

In some cases, MySQL cannot use indexes to resolve the ORDER BY, although it still uses indexes to find the rows that match the WHERE clause. 在某些情况下,MySQL无法使用索引来解析ORDER BY,尽管它仍然使用索引来查找与WHERE子句匹配的行。 These cases include the following: ––– You use ORDER BY on nonconsecutive parts of a key: SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2; 这些情况包括:–在密钥的非连续部分上使用ORDER BY:SELECT * FROM t1 WHERE key2 = constant ORDER BY key_part2;

Maybe this applies to your query since you have a composite KEY ids (imageid,adate) and you don't use imageid in your ORDER BY . 也许这适用于您的查询,因为您有复合的KEY ids (imageid,adate)并且在ORDER BY不使用imageid You could try and add a key for adate only and see if that helps. 你可以尝试,并添加一个键adate只有看看有没有什么帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM