Con*_*ion 9 mysql indexing sql-order-by query-optimization
我有一个MySQL表:
CREATE TABLE mytable (
id INT NOT NULL AUTO_INCREMENT,
other_id INT NOT NULL,
expiration_datetime DATETIME,
score INT,
PRIMARY KEY (id)
)
Run Code Online (Sandbox Code Playgroud)
我需要以下列形式运行查询:
SELECT * FROM mytable
WHERE other_id=1 AND expiration_datetime > NOW()
ORDER BY score LIMIT 10
Run Code Online (Sandbox Code Playgroud)
如果我将此索引添加到mytable:
CREATE INDEX order_by_index
ON mytable ( other_id, expiration_datetime, score);
Run Code Online (Sandbox Code Playgroud)
MySQL能否order_by_index在上面的查询中使用整个?
现在看来似乎应该是可以的,但后来根据MySQL的文档:" 该指数还可以用来即使ORDER BY不索引完全一致,只要所有索引的未使用部分和所有的额外ORDER BY列是WHERE子句中的常量. "
上面的段落似乎表明索引只能用于常量查询,而我的是范围查询.
任何人都可以澄清在这种情况下是否会使用索引?如果没有,我可以用任何方式强制使用索引吗?
谢谢.
MySQL将使用索引来满足where子句,并将使用filesort来对结果进行排序.
它不能使用order by作为order by,因为你没有将expiration_datetime与一个常量进行比较.因此,返回的行并不总是在索引中都有一个公共前缀,因此索引不能用于排序.
例如,考虑一下包含4个索引记录的示例集:
a) [1,'2010-11-03 12:00',1]
b) [1,'2010-11-03 12:00',3]
c) [1,'2010-11-03 13:00',2]
d) [2,'2010-11-03 12:00',1]
Run Code Online (Sandbox Code Playgroud)
如果我在2010-11-03 11:00运行您的查询,它将返回在索引中不连续的行a,c,d.因此,MySQL需要执行额外的传递来对结果进行排序,并且在这种情况下不能使用索引.
任何人都可以澄清在这种情况下是否会使用索引?如果没有,我可以用任何方式强制使用索引吗?
您的过滤条件ORDER BY范围与范围不匹配.
这些条件不能用单个索引提供.
要选择要创建的索引,您需要运行这些查询
SELECT COUNT(*)
FROM mytable
WHERE other_id = 1
AND (score, id) <
(
SELECT score, id
FROM mytable
WHERE other_id = 1
AND expiration_datetime > NOW()
ORDER BY
score, id
LIMIT 10
)
Run Code Online (Sandbox Code Playgroud)
和
SELECT COUNT(*)
FROM mytable
WHERE other_id = 1
AND expiration_datetime >= NOW()
Run Code Online (Sandbox Code Playgroud)
并比较他们的输出.
如果第二个查询产生与第一个查询大约相同或更多的值,那么您应该使用索引(other_id, score)(并让它过滤expiration_datetime).
如果第二个查询产生的值远远少于第一个查询,则应该使用索引(other_id, expiration_datetime)(并让它排序score).
这篇文章可能对你很有意思: