8.2.1.19 Optimizing LIMIT Queries 优化LIMIT 查询:
如果你只需要记录的特定列从一个结果集,使用一个LIMIT 子句在一个查询里,
而不是获取整个结果集,扔掉额外的数据。
MySQL 有时候优化一个查询有一个LIMIT row_count 子句,没有HAVING 子句:
如果你只选择一小部分的记录使用LIMIT,MySQL 使用indexed 在一些例子里,
通常它宁愿选择做一个全表扫描:
如果你结合LIMIT row_count 和ORDER BY,MySQL 结束排序在它发现第一个row_count ,
而不是整个结果 。如果排序是通过使用一个索引,这是很快的。
如果一个filesort 必须被做, 所有匹配查询的记录没有LIMIT 子句是被选择的,
大多数或者全部被存储, 在row_count 被找到前。
在初始的记录被找到后,MySQL 不排序任何剩余的结果集。
这种行为的一种表现是ORDER BY 查询使用和不使用LIMIT 可能返回记录按不同的顺序
在后面的章节描述:
如果你组合LIMIT row_count 使用DISTINCT, MySQL 只要找到row_count unique 记录就停止。
在一些例子中,一个GROUP BY 可以通过读取index 来解决按顺序(或者在索引上做一个排序)
然后计算汇总直到Index value 改变。在这种情况下,LIMIT row_count 不计算任何不需要GROUP BY 的值
当MySQL 已经发送 需要的记录给客户端, 它终止查询除非你使用SQL_CALC_FOUND_ROWS.
行数然后检索用SELECT FOUND_ROWS().
LIMIT 0 快速的返回一个空的结果集, 这个可以用于检查一个查询的正确性。
它也可以被用来获得结果列的类型 如果你使用一个MySQL API,
使结果集数据可用。 与mysql 客户端程序, 你可以使用–column-type-info 选项来显示结果列类型。
如果server 使用临时表来解决查询,它使用LIMIT row_count 子句来计算需要的空间。
如果多行具有相同的值在ORDER BY 列里, server 可以自由的返回继续以任何的排序,
并根据总体的执行计划来进行不同的方式,换句话说,这些行的排序顺序是不确定的。
一个因素影响执行计划是LIMIT, 因为一个ORDER BY 查询 有和没有LIMIT 可能返回不同顺序的记录。
考虑这个查询, 是按类型列排序,但是不确定是相对于ID和rating列。
mysql> SELECT * FROM ratings ORDER BY category;
+—-+———-+——–+
| id | category | rating |
+—-+———-+——–+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 3 | 2 | 3.7 |
| 4 | 2 | 3.5 |
| 6 | 2 | 3.5 |
| 2 | 3 | 5.0 |
| 7 | 3 | 2.7 |
+—-+———-+——–+
包括LIMIT 可能影响每一类值的记录的顺序,例如, 这是一个正确的查询结果:
mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+—-+———-+——–+
| id | category | rating |
+—-+———-+——–+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 4 | 2 | 3.5 |
| 3 | 2 | 3.7 |
| 6 | 2 | 3.5 |
+—-+———-+——–+
在每一种情况下, 记录按ORDER BY 列排序, 这是SQL标准需要的:
如果它是重要的 确认相同的记录有和没有LIMIT,包括额外的列 在ORDER BY 子句来确定顺序。
比如,如果id 值是唯一的:
mysql> SELECT * FROM ratings ORDER BY category, id;
+—-+———-+——–+
| id | category | rating |
+—-+———-+——–+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 3 | 2 | 3.7 |
| 4 | 2 | 3.5 |
| 6 | 2 | 3.5 |
| 2 | 3 | 5.0 |
| 7 | 3 | 2.7 |
+—-+———-+——–+
mysql> SELECT * FROM ratings ORDER BY category, id LIMIT 5;
+—-+———-+——–+
| id | category | rating |
+—-+———-+——–+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 3 | 2 | 3.7 |
| 4 | 2 | 3.5 |
| 6 | 2 | 3.5 |
+—-+———-+——–+
在MySQL 5.6.2, 优化器会更有效的处理查询(子查询)如下:
SELECT … FROM single_table … ORDER BY non_index_column [DESC] LIMIT [M,]N;
这种类型的查询是常见的,显示少数行从一个大的结果集:
SELECT col1, … FROM t1 … ORDER BY name LIMIT 10;
SELECT col1, … FROM t1 … ORDER BY RAND() LIMIT 15;
sort buffer 有一个sort_buffer_size参数,如果sort 原理用于N条记录是足够小的 放入sort buffer
(M+N 记录如果M被指定), server 可以避免使用一个合并文件,执行整个排序在内存里
通过处理sort buffer 作为优化队列