【问题标题】:Avoid full table scan in mysql while using order by with limit使用带限制的 order by 时避免在 mysql 中进行全表扫描
【发布时间】:2012-02-13 02:45:39
【问题描述】:

我正在写一个查询:

select * from table_name order by id limit 21

在我使用限制小于或等于 20 之前,扫描的行等于准确的获取行(例如,如果限制为 10,则扫描的行也只有 10)。如果限制超过 20,则表将被完全扫描。

仅为主键 id 创建的唯一一个索引。有人能说出这种情况下全表扫描的原因吗?


我的表有 1099 行。

Explain Result:
---------------------------------------------------------------------------
id|selecttype|table |type|possiblekeys|keys|key_len|ref |rows|  Extra       
---------------------------------------------------------------------------
1 | SIMPLE   |tablen|ALL |  null      |null|null   |null|1099|Usingfilesort 
---------------------------------------------------------------------------

【问题讨论】:

  • 你确定你在table_name(id)上有索引吗?
  • 你能像这样测试你的查询吗:select id from table_name order by id limit 21,请在你的问题中添加解释结果和表结构
  • 查询慢吗?表有多少行?如果您只有几百行,那么对 LIMIT 100 进行整体扫描是优化器认为更快的方法。
  • 请提供您的表格结构
  • 请不要将回复作为答案发布,如果您想添加更多信息,请编辑您的问题,或将 cmets 留在您收到的答案下方。

标签: mysql indexing sql-order-by


【解决方案1】:

一般情况下,要返回LIMIT M, N 的行,MySQL 必须扫描没有LIMIT 的结果的 M+N 行,并跳过其中的前 M-1 行,因此是全表扫描。

在您的案例中,前 20 行似乎适合单个页面,并且由于您按主键排序,MySQL 可能明白它不需要进行全表扫描。

还有一点要知道,对于SELECT * FROM T ORDER BY something这样的查询,MySQL通常不会使用任何索引,通常在有条件时使用索引,或者如果可以直接从索引中获取所有数据(覆盖索引)。

【讨论】:

  • 感谢您的信息。在这种情况下有没有其他方法可以限制扫描。
  • 嗨@newtovar,你能看看我的问题,这与你的答案有关,我在代码中使用索引列,但遇到相同的扫描问题。这是链接stackoverflow.com/questions/53350515/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
  • 2021-12-08
  • 1970-01-01
  • 2022-07-25
相关资源
最近更新 更多