[英]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选择数据并用日期对其进行排序,所以我添加了(
imageid
, adate
)键。
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.