8.2.1.19 Optimizing LIMIT Queries 优化LIMIT 查询:

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 作为优化队列

原文地址:https://www.cnblogs.com/hzcya1995/p/13351276.html