我有这样的表,我用它来在 mysql 中实现队列:
CREATE TABLE `queue` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `queue_name` varchar(255) NOT NULL, `inserted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `inserted_by` varchar(255) NOT NULL, `acquired` timestamp NULL DEFAULT NULL, `acquired_by` varchar(255) DEFAULT NULL, `delayed_to` timestamp NULL DEFAULT NULL, `priority` int(11) NOT NULL DEFAULT '0', `value` text NOT NULL, `status` varchar(255) NOT NULL DEFAULT 'new', PRIMARY KEY (`id`), KEY `queue_index` (`acquired`,`queue_name`,`priority`,`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
我的问题是 mysql 在我运行更新时使用文件排序。执行速度非常慢(表中 80 万行需要 5 秒)。
DESCRIBE UPDATE queue SET acquired = "test" WHERE acquired IS NULL AND queue_name = "q1" ORDER BY priority, id LIMIT 1;
+----+-------------+-------+-------+---------------+-------------+---------+-------------+--------+-----------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+-------------+---------+-------------+--------+-----------------------------+ | 1 | SIMPLE | queue | range | queue_index | queue_index | 772 | const,const | 409367 | Using where; Using filesort | +----+-------------+-------+-------+---------------+-------------+---------+-------------+--------+-----------------------------+
奇怪的是,当我使用相同的 WHERE 条件运行 SELECT 查询并且未使用 ORDER 列文件排序时:
DESCRIBE SELECT id FROM queue WHERE acquired IS NULL AND queue_name = "q1" ORDER BY priority, id LIMIT 1;
+----+-------------+-------+------+---------------+-------------+---------+-------------+--------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+-------------+---------+-------------+--------+--------------------------+ | 1 | SIMPLE | queue | ref | queue_index | queue_index | 772 | const,const | 409367 | Using where; Using index | +----+-------------+-------+------+---------------+-------------+---------+-------------+--------+--------------------------+
(查询时间0s)
有谁知道如何避免在更新查询中使用文件排序或如何提高其性能?
问候, 马兹
最佳答案
在 mysql 论坛 ( http://forums.mysql.com/read.php?24,620908,620908#msg-620908 ) 上讨论后,我报告了错误 http://bugs.mysql.com/bug.php?id=74049 (已验证)。 使用 SELECT FOR UPDATE 可以绕过问题:
SET @update_id := -1;
SELECT (SELECT @update_id := id)
FROM queue
WHERE acquired IS NULL AND queue_name = "q1"
ORDER BY priority, id LIMIT 1;
FOR UPDATE;
UPDATE queue SET acquired = "test" WHERE id = @update_id;
关于mysql - 消除更新查询中的mysql文件排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25976390/