mysql - 消除更新查询中的mysql文件排序

标签 mysql sql query-optimization filesort

我有这样的表,我用它来在 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/

相关文章:

MySQL 重复错误与 ALTER IGNORE TABLE

php - 如何将表 User、Offers 和 Car 与关系 mysql Laravel 连接起来

mysql - 需要创建域以将表中的值限制为特定值,不断出现错误

mysql - 迁移问题 : MS SQL > MySQL: Insert Buffer Memory

多个 FULLTEXT 索引上的 MySQL SELECT。结果极其缓慢

mysql - 针对 max、count 优化 MySQL InnoDB 查询

php - 如果我总是使用 PHP 控制我的数据库输入,像 NOT NULL 和 FOREIGN KEY 这样的约束有多重要?

sql - 如何使用单个查询将多个对象表中的记录连接到主表?

sql - 如何处理从类型 'DBNull' 到类型 'Integer' 的转换无效

mysql - 如何优化简单 Web 和数据库应用程序的响应时间