【问题标题】:How to stop LIMIT from slowing down query?如何阻止 LIMIT 减慢查询速度?
【发布时间】:2014-01-30 14:48:06
【问题描述】:

我创建了一个包含 100k 行的测试表。此查询的执行时间:

SELECT id FROM table

0.032s。如果我为索引为Normal,BTREE 的整数列添加GROUP BY 语句,则查询的执行时间:

SELECT id FROM table GROUP BY indexedColumn

解释输出:

id | select_type | table | type |    possible keys   | key  | key_len | ref |  rows  | Extra
 1      SIMPLE    [table]  All    [indexedColumnKey]   null    null    null   105416   Using temporary; Using filesort

0.073s。由于GROUP BY,执行时间增加了一倍,但我假设这是正常的?我的问题是,为什么要在查询中添加LIMIT,如下所示:

SELECT id FROM table GROUP BY indexedColumn LIMIT 500

解释输出:

id | select_type | table | type |      possible keys    |        key        | key_len | ref |  rows  | Extra
 1      SIMPLE    [table]  index    [indexedColumnKey]   [indexedColumnKey]      5      null   500     null

将执行时间增加到0.301s?这是超过 4 倍的减速。

我对 SQL 非常缺乏经验,所以这可能是完全正常的,但对我来说,限制返回的行数会大大降低查询速度,这似乎违反直觉。

问题:

  1. 这正常吗?
  2. 有没有什么办法可以阻止 LIMIT 如此降低查询速度?

【问题讨论】:

  • 你是如何衡量这个的?
  • 如果你在查询前加上解释,你会得到计划,怀疑它是在做二次排序来发现“第一个”500。
  • 第二个(和第三个)查询(SELECT id FROM table GROUP BY indexedColumn)没有意义,如果启用ONLY_FULL_GROUP_BY设置会产生错误。想一想,对于indexedColumn 的任何值,id 的值都有很多。应该退回哪一个? (如果您想知道,是的,当该设置未启用时,MySQL 确实会返回一个任意值。)
  • 总之不要这样使用GROUP BY
  • 与您的问题无关,但使用没有 order by 子句的限制可能毫无意义。你是说你只想要 500 条记录,但没有指定哪 500 条记录。

标签: mysql sql sql-limit


【解决方案1】:

查询SELECT id FROM table GROUP BY indexedColumn 不使用索引。它显示在您的解释中。但是当您使用限制时,将使用索引。 此外,对于实验,您可以使用 SQL_NO_CACHE SELECT SQL_NO_CACHE .... 禁用缓存

【讨论】:

  • 索引不应该让它更快,而不是更慢吗?
  • @Nate,index 应该让它更快。请set profiling=1; 使用 SQL_NO_CACHE 运行第一个查询,然后在show profiles; 之后运行第二个查询并发布结果;
猜你喜欢
  • 2017-12-02
  • 2011-10-04
  • 2015-11-27
  • 2017-12-24
  • 2011-05-27
  • 2016-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多