请考虑包含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
!
我做错了什么?
答案 0 :(得分:2)
确实 ORDER BY 子句会降低查询性能,因为数据库需要在给出最终输出之前缓冲中间结果。
原因:无法以管道方式执行排序操作。必须在输出生成之前完全读取输入。
ORDER BY子句的替代方法可以是 INDEXING 。索引使数据保持有序,这就是如何减少ORDER BY子句中的排序开销。
答案 1 :(得分:1)
(除了Harshita的答案:)
如果您添加ORDER BY
,那么无论有没有WHERE
,查询都会更快。
请注意 复合索引处理所有ORDER BY
过滤,并且仍然有ORDER BY
列来处理LIMIT
和{{ 1}}。
更多强>
EXPLAIN
显示该索引的使用;此外,它说“使用索引”。这意味着索引是“覆盖”,这意味着查询完全在索引中执行,而不需要触摸数据。
无论您是否拥有EXPLAIN
,我都希望ORDER BY
相同。是吗?
什么是“prs”? “RPS”?也许“每秒请求”?取决于正在进行的其他操作以及buffer_pool中块的缓存。 50-200的变化似乎是合理的。是否有多个线程可用于下一个项目?是否有UPDATE
或DELETE
您没有提及在找到项目后“删除”该项目?这比<{1}} 影响;我们应该在同一时间讨论这个问题。
如果您使用表作为队列,最终会遇到性能不佳的情况。我的口头禅是:“不要排队,只是这样做。”