【问题标题】:mysql ORDER BY isn't using the index when multiple fields are present in SELECT当 SELECT 中存在多个字段时,mysql ORDER BY 不使用索引
【发布时间】:2012-03-11 10:21:37
【问题描述】:

我正在尝试简化查询以找出为什么它在生产服务器上如此缓慢。这个想法是抓取 X 个最新条目进行分页。问题是,MySQL 的优化器似乎想要使用文件排序而不是主键 (ID)。使用索引(主要)去除所有无关的东西,以下工作按需要进行:

EXPLAIN SELECT ID FROM table ORDER BY ID DESC

但是,这些变体求助于文件排序:

EXPLAIN SELECT ID, field2 FROM table ORDER BY ID DESC
EXPLAIN SELECT * FROM table ORDER BY ID DESC

我需要返回几个字段,所以这不起作用...我可以通过以下方式解决简化查询中的问题:

EXPLAIN SELECT * FROM table FORCE INDEX (Primary) ORDER BY ID DESC

但我还没有弄清楚如何通过表连接将其用于更大的查询。我错过了一些非常简单的东西吗?

【问题讨论】:

  • 强制使用索引会加快查询速度吗?如果您需要读取表的所有记录(就像您所做的那样),那么使用索引可能没有意义。 “这个想法是抓取 X 个最近的条目进行分页”。然后在某处应该有 LIMIT 子句。否则数据库认为你想要它们。
  • 抱歉,我没有提到 LIMIT 子句,因为这是我为上述示例删除的部分内容。设置 LIMIT 似乎没有任何效果——它仍然每次都使用文件排序。我没有让它在生产服务器上使用 FORCE INDEX 运行速度测试;仅通过 EXPLAIN 测试。

标签: mysql indexing sql-order-by optimization


【解决方案1】:

试试这个查询

select * from table order by id desc limit (pageNO-1) * noEntries , noEntries

例如,对于第 1 页和每页 10 个条目

 select * from table order by id desc limit 0, 10

例如对于第 2 页和每页 10 个条目

select * from table order by id desc limit 10, 10

【讨论】:

  • 见上面我对 Thilo 的回复。添加 LIMIT 子句仍然使用文件排序。这就是让我一开始感到困惑的部分,导致我剥离所有碎片,直到我能更好地了解发生了什么。
【解决方案2】:

问题解决了!我经历了无数次修改,不能发誓哪个是关键,但我认为主要是运行 OPTIMIZE TABLE,它具有以下清理效果:

Type        Usage
Data        241.2 KiB -> 239.4
Index       31,744 B  -> 26,624
Overhead    136 B     -> 0
Effective   272.0 KiB
Total       272.2 KiB -> 265.4

这样,我就可以运行“EXPLAIN SELECT ID, field2 FROM table ORDER BY ID DESC LIMIT 0,10”,而无需使用文件排序,这是一个好的开始。从那里,我开始再次构建主查询,并遇到了 DISTINCT(ID) 的问题,使其无法使用主键作为索引。但是,它必须存在,因为 ID 字段连接的表之一对于每个 ID 都有多个条目。但是,将 DISTINCT(ID) 替换为 GROUP BY ID 就可以了。这以前不起作用,所以我想知道它是否与 OPTIMIZE TABLE 有关?无论如何,感谢您在我投入使用时提供的帮助!

【讨论】:

  • 这有点暗示,但我应该提到让查询使用索引而不是文件排序对性能有巨大影响。以前,它似乎会无限期地挂起,而现在它几乎是瞬间的。
猜你喜欢
  • 1970-01-01
  • 2011-09-29
  • 2012-03-27
  • 2023-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-13
  • 1970-01-01
相关资源
最近更新 更多