我有一个MySQL InnoDB表,events
,有3行:
event_id ---> int
start ---> long
end ---> long
我编写了一个简单的查询,用于获取某个范围内与另一个事件冲突的所有事件:
select a.* from events a, events b
where a.event_id != b.event_id and
a.start < b.end and
b.start < a.end
该表有~10K行,需要约2秒才能执行。在尝试使用表格进行调整以提高性能时,我在start
和end
列上添加了索引。出于某种原因,这显着减慢了性能因子 5x 。有谁知道,或有任何想法,为什么添加这些指数会损害表现不好?
答案 0 :(得分:1)
MySQL查看所涉及的列,并误以为索引将有助于改进查询。但问题是索引解决了起始端部分,但需要解析回记录ID以解析a.event_id!= b.event_id,这本身就是一项昂贵的操作。
没有索引强制进行交叉连接和过滤,虽然可能会产生大量的临时记录,但实现起来要简单得多。
如果您的查询受a或b的某个范围限制,而不是起始端,和/或表格大于10k,则可能会成为非常不同的图片。
如果您需要保留索引,可以强制特定查询(如果您知道这有帮助)忽略索引:
select a.*
from events a ignore index (index1)
cross join events b ignore index (index1)
where a.event_id != b.event_id and
a.start < b.end and
b.start < a.end
假设索引名为index1。在任何情况下,通过在查询之前添加“EXPLAIN”以显示MySQL如何收集结果(没有索引,索引,索引但忽略)来查看MySQL在每种情况下做什么总是有帮助的。