当前位置: 首页 > 知识库问答 >
问题:

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

商茂勋
2023-03-14

我有这样一个表,用于在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使用了filesort。执行速度非常慢(对于表中800k行,执行速度为5s)。

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 |
+----+-------------+-------+-------+---------------+-------------+---------+-------------+--------+-----------------------------+
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 |
+----+-------------+-------+------+---------------+-------------+---------+-------------+--------+--------------------------+

有人知道如何避免在更新查询中使用filesort或如何提高其性能吗?

问候,Matzz

共有1个答案

张和豫
2023-03-14

经过mysql论坛(http://forums.mysql.com/read.php?24,620908,620908msg-620908)的讨论,我报告了bug http://bugs.mysql.com/bug.php?id=74049(已验证)。可以使用选择更新绕过问题:

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;
 类似资料:
  • 我正在尝试使用query-更新行(删除列str_column中的连字符和连字符后的所有字符)- 但上面的查询是删除匹配的行而不是更新。 我不明白,如何更新查询可以删除行??

  • 问题内容: 谁能帮助我了解为什么此更新查询未更新数据库中的字段?我在我的php页面中有这个来从数据库中检索当前值: 这是我的HTML表单: 这是我的“ editblogscript”: 我不明白为什么它不起作用。 问题答案: 您必须在查询中的所有VARCHAR内容周围加上单引号。因此,您的更新查询应为: 同样,用POST中的内容直接更新数据库是一种不好的形式。您应该使用mysql_real_esc

  • 问题内容: 谁能看到以下查询出了什么问题? 当我运行它时,我得到: #1064-您的SQL语法有误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在第8行的’a where a.CompetitionID = Competition.CompetitionID’附近使用 问题答案: 主要问题是内部查询不能与外部语句上的子句相关,因为在内部子查询执行之前,where过滤器首先应用于要

  • 我需要更新我的数据库,它是基于locationId的多行软删除 当我运行查询时,我得到一个错误: 错误代码:1175。您使用的是安全更新模式,并且您试图更新一个没有使用键列禁用安全模式的表,请在“首选项”中切换该选项- 正如我所知,子查询将返回两条记录,因为子查询返回两条记录更新不会发生,但我如何解决这个问题。我试图解决这个问题,但没有成功。

  • 我正在使用MySql工作台执行查询。 但它没有更新行,并显示以下错误: 您正在使用安全更新模式,并且试图更新一个没有使用键列禁用安全模式的WHERE的表,请在Preferences->SQL Editor中切换该选项并重新连接。

  • 问题内容: 我已将此代码用于提供+1分,但无法正常工作。 $ points变量现在是用户的点数。.我希望它加上一个点数。.例如,如果他有5个点数,它应该是5 + 1 =6。 但是没有,它只是改变了到1 我做错了什么?谢谢 问题答案: 您也可以这样做: