MySQL:ORDER BY 显着降低查询速度
Posted
技术标签:
【中文标题】MySQL:ORDER BY 显着降低查询速度【英文标题】:MySQL: ORDER BY significantly slows the query 【发布时间】:2017-10-13 05:34:37 【问题描述】:请考虑一个包含queue_name
、priority
和message_timestamp
列的表。
我将执行以下查询:
SELECT message_timestamp
from queue_messages
WHERE queue_name = 'name'
AND state = 0
ORDER
BY message_timestamp DESC
LIMIT 1
这是一个复合索引:
CREATE INDEX STATE_QUEUENAME_TIMESTAMP ON `queue_messages` (queue_name, state, message_timestamp);
EXPLAIN 显示索引与查询匹配得很好(ORDER BY
没有文件排序):
我的问题是,如果没有 ORDER BY message_timestamp
,这个查询的吞吐量约为 200 prs,但有 ~50 rps!
表中的行越多,ORDER BY
的查询速度就越慢!
我做错了什么?
【问题讨论】:
好吧,如果order by
会降低大表的查询性能,这是意料之中的。
【参考方案1】:
(除了Harshita的回答:)
如果添加INDEX(queue_name, state, message_timestamp)
,则无论是否使用ORDER BY
,查询都会更快地运行。
注意那个复合索引处理所有WHERE
过滤,并且仍然有ORDER BY
列来处理ORDER BY
和LIMIT
。
更多
EXPLAIN
显示该索引的使用;此外,它说“使用索引”。即索引是“覆盖”的,即查询完全在索引中进行,不需要接触数据。
无论您是否拥有ORDER BY
,我都希望EXPLAIN
相同。是吗?
什么是“prs”? “rps”?也许“每秒请求数”?取决于其他情况以及 buffer_pool 中块的缓存。 50-200 的变化似乎是合理的。是否有多个线程到达下一个项目?是否有 UPDATE
或 DELETE
没有提到在找到该项目后“删除”该项目?这将比SELECT
产生更大的影响;我们真的应该同时讨论这个问题。
如果您将表用作队列,您最终会遇到性能不佳的情况。我的口头禅是:“不要排队,就去做吧”。
【讨论】:
对不起,你说的是我在问题中描述的同一个索引,还是我错过了什么? 更多讨论,还有更多问题等你来回答。【参考方案2】:ORDER BY 子句确实会降低查询的性能,因为数据库需要在给出最终输出之前缓冲中间结果。
原因:排序操作不能以流水线方式执行。在产生输出之前,必须完全读取输入。
ORDER BY 子句的替代可以是INDEXING。索引使您的数据保持有序,这就是减少在 ORDER BY 子句中排序的开销的方法。
【讨论】:
以上是关于MySQL:ORDER BY 显着降低查询速度的主要内容,如果未能解决你的问题,请参考以下文章