【问题标题】:Why does MySQL ignore index on ORDER BY为什么 MySQL 忽略 ORDER BY 上的索引
【发布时间】:2014-09-25 21:40:01
【问题描述】:

我一直在努力解决这个问题,但没有运气。我在我的小站点上实现了一个简单的队列系统和一个 cron 作业来检查队列中是否有任何项目。它应该获取按优先级排序的几个项目并处理它们,但由于某种原因,优先级索引被忽略了。我的创建表语法是

CREATE TABLE `site_queue` (
  `row_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `task` tinyint(3) unsigned NOT NULL COMMENT '0 - email',
  `priority` int(10) unsigned DEFAULT NULL,
  `commands` text NOT NULL,
  `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`row_id`),
  KEY `task` (`task`),
  KEY `priority` (`priority`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

获取排队项目的查询是

SELECT `row_id`, `task`, `commands` FROM `site_queue` ORDER BY `priority` DESC LIMIT 5;

EXPLAIN 查询返回以下内容:

+----+-------------+------------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+------------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | site_queue | ALL  | NULL          | NULL | NULL    | NULL | 1269 | Using filesort |
+----+-------------+------------+------+---------------+------+---------+------+------+----------------+

任何人都可以提供一些可能导致此问题的原因吗?

【问题讨论】:

  • 如果将priority 包含在select 列表中会怎样?
  • 还是太少了。添加 10-50k 行怎么样?
  • 我刚刚尝试添加 - 仍然是文件排序。
  • 顺便说一句,priority 列的基数是多少?
  • 优先级,默认情况下,是一个 UNIX_TIMESTAMP() + 一个优先级系数,所以它总是大致等于行数。添加 50k 行使 EXPLAIN 结果打印 possible_keys = NULL,key = priority,所以我想这确实是行数问题 - 谢谢!您能否将其添加到您的答案中,以便有相同问题的其他人在我接受时可以立即看到解决方案(或者更确切地说是不需要解决方案)?

标签: mysql indexing sql-order-by


【解决方案1】:

因为当它只有几行时(最初是 4 行,然后增加到 1k),没有理由使用索引,因为它会更慢(mysql 将不得不多次读取索引和数据页)。

因此,mysql 查询优化的经验法则:当你这样做时,使用相当大量的数据。如果大小与实际生产数据大小相当。

【讨论】:

  • 我已经编辑了我的问题,在 1200 行中包含一个 EXPLAIN 结果——在生产环境中,队列不太可能超过 1000;遗憾的是,问题仍然存在。
猜你喜欢
  • 2012-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
相关资源
最近更新 更多