2017-05-14 67 views
0

请考虑一个表queue_name,prioritymessage_timestamp列。MySQL的ORDER BY:不同的EXPLAIN的SELECT和UPDATE

这里是一个复合索引:

CREATE INDEX STATE_QUEUENAME_PRIORITY_TIMESTAMP ON 
     `queue_messages` (queue_name, state, priority, message_timestamp); 

解释SELECT:(!用相同WHEREORDER BY

EXPLAIN SELECT message_timestamp 
     from queue_messages 
     WHERE queue_name = 'folder' 
      AND state = 0 
     ORDER BY priority DESC, message_timestamp DESC 
       LIMIT 1; 

返回Using where; Using index

解释UPDATE:

EXPLAIN UPDATE queue_messages 
     SET  state = 1 
     WHERE queue_name = 'folder' 
      AND state = 0 
     ORDER BY priority DESC, message_timestamp DESC 
       LIMIT 1; 

返回Using where; Using filesort

-

它会导致显著的性能影响(20ms的选择VS 90毫秒UPDATE上50,000列)。

如何强制MariaDB(MySQL)在UPDATE语句中删除filesort

+0

你可以尝试给一个索引提示https://dev.mysql.com/doc/refman/5.7/en/index-hints.html – RiggsFolly

+0

我不知道肯定,但你正在更新状态,这是属于关键所以也许你不能。 –

+0

这是唯一的索引吗? –

回答

0

update,你需要第二个指标:

CREATE INDEX STATE_QUEUENAME_TIMESTAMP_2 ON `queue_messages` (queue_name, state, priority, message_timestamp); 

您现有的指数不包括priority,所以它不能用于order by

+0

我很抱歉,我认为复制粘贴错误的索引声明。你是对的,我已经使用了所有4个领域的索引。使用正确的索引更新了问题:'STATE_QUEUENAME_PRIORITY_TIMESTAMP' –

+0

其实这就是为什么我想知道 - SELECT查询完美匹配索引,但更新与完全相同的WHERE/ORDER子句 - 不是。 –