【发布时间】: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 非常缺乏经验,所以这可能是完全正常的,但对我来说,限制返回的行数会大大降低查询速度,这似乎违反直觉。
问题:
- 这正常吗?
- 有没有什么办法可以阻止 LIMIT 如此降低查询速度?
【问题讨论】:
-
你是如何衡量这个的?
-
如果你在查询前加上解释,你会得到计划,怀疑它是在做二次排序来发现“第一个”500。
-
第二个(和第三个)查询(
SELECT id FROM table GROUP BY indexedColumn)没有意义,如果启用ONLY_FULL_GROUP_BY设置会产生错误。想一想,对于indexedColumn的任何值,id的值都有很多。应该退回哪一个? (如果您想知道,是的,当该设置未启用时,MySQL 确实会返回一个任意值。) -
总之不要这样使用
GROUP BY。 -
与您的问题无关,但使用没有 order by 子句的限制可能毫无意义。你是说你只想要 500 条记录,但没有指定哪 500 条记录。