8.2.1.17 LIMIT 查询优化

如果从结果集中只需要指定数量的行,请在查询中使用LIMIT子句,而不要获取整个结果集并丢弃多余的数据。

MySQL 有时会优化具有LIMIT row_count子句而没有HAVING子句的查询:

此行为的一种体现是,具有和不具有LIMITORDER BY查询可能以不同的 Sequences 返回行,如本节稍后所述。

如果ORDER BY列中的多行具有相同的值,则服务器可以自由地以任何 Sequences 返回这些行,并且根据整体执行计划,这样做的方式可能有所不同。换句话说,这些行的排序 Sequences 相对于无序列是不确定的。

影响执行计划的一个因素是LIMIT,因此具有LIMIT和不具有LIMITORDER BY查询可能以不同的 Sequences 返回行。考虑以下查询,该查询按category列排序,但相对于idrating列不确定:

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可能会影响每个category值中的行 Sequences。例如,这是一个有效的查询结果:

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和不带有LIMIT的行 Sequences 相同,请在ORDER BY子句中包括其他列以使 Sequences 确定。例如,如果id值是唯一的,则可以通过以下排序使给定category值的行以idSequences 显示:

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 |
+----+----------+--------+
首页