If you need only a specified number of rows from a result set, use a 如果只需要结果集中指定数量的行,请在查询中使用LIMIT
clause in the query, rather than fetching the whole result set and throwing away the extra data.LIMIT
子句,而不是获取整个结果集并丢弃额外的数据。
MySQL sometimes optimizes a query that has a MySQL有时会优化具有LIMIT
clause and no row_count
HAVING
clause:LIMIT
子句并且无row_count
HAVING
子句的查询:
If you select only a few rows with 如果您利用LIMIT
, MySQL uses indexes in some cases when normally it would prefer to do a full table scan.LIMIT
只选择了几行,MySQL在某些情况下会使用索引,而通常它更愿意执行完整表扫描。
If you combine 如果将LIMIT
with row_count
ORDER BY
, MySQL stops sorting as soon as it has found the first row_count
rows of the sorted result, rather than sorting the entire result. LIMIT
与row_count
ORDER BY
结合使用,MySQL会在找到排序结果的最前面的row_count
个行后立即停止排序,而不是对整个结果进行排序。If ordering is done by using an index, this is very fast. 如果使用索引进行排序,则速度非常快。If a filesort must be done, all rows that match the query without the 如果必须进行文件排序,则在找到最前面的LIMIT
clause are selected, and most or all of them are sorted, before the first row_count
are found. row_count
个行之前,将选择与查询匹配但没有LIMIT
子句的所有行,并对其中的大部分或全部进行排序。After the initial rows have been found, MySQL does not sort any remainder of the result set.在找到初始行之后,MySQL不会对结果集的任何剩余部分进行排序。
One manifestation of this behavior is that an 这种行为的一种表现形式是,有ORDER BY
query with and without LIMIT
may return rows in different order, as described later in this section.LIMIT
和无LIMIT
的ORDER BY
查询可能以不同的顺序返回行,如本节后面所述。
If you combine 如果将LIMIT
with row_count
DISTINCT
, MySQL stops as soon as it finds row_count
unique rows.LIMIT
与row_count
DISTINCT
结合起来,MySQL会在找到row_count
个唯一行时立即停止。
In some cases, a 在某些情况下,可以通过按顺序读取索引(或对索引进行排序),然后计算摘要,直到索引值发生变化来解析GROUP BY
can be resolved by reading the index in order (or doing a sort on the index), then calculating summaries until the index value changes. GROUP BY
。In this case, 在这种情况下,LIMIT
does not calculate any unnecessary row_count
GROUP BY
values.LIMIT
不会计算任何不必要的row_count
GROUP BY
值。
As soon as MySQL has sent the required number of rows to the client, it aborts the query unless you are using 一旦MySQL向客户端发送了所需数量的行,它就会中止查询,除非您使用的是SQL_CALC_FOUND_ROWS
. SQL_CALC_FOUND_ROWS
。In that case, the number of rows can be retrieved with 在这种情况下,可以使用SELECT FOUND_ROWS()
. SELECT FOUND_ROWS()
检索行数。See Section 12.16, “Information Functions”.请参阅第12.16节,“信息功能”。
LIMIT 0
quickly returns an empty set. LIMIT 0
快速返回一个空集。This can be useful for checking the validity of a query. 这对于检查查询的有效性非常有用。It can also be employed to obtain the types of the result columns within applications that use a MySQL API that makes result set metadata available. 它还可以用于获取应用程序中的结果列的类型,这些应用程序使用MySQL API使结果集元数据可用。With the mysql client program, you can use the 使用mysql客户端程序,可以使用--column-type-info
option to display result column types.--column-type-info
选项显示结果列类型。
If the server uses temporary tables to resolve a query, it uses the 如果服务器使用临时表来解析查询,它将使用LIMIT
clause to calculate how much space is required.row_count
LIMIT
子句来计算需要多少空间。row_count
If an index is not used for 如果索引未用于ORDER BY
but a LIMIT
clause is also present, the optimizer may be able to avoid using a merge file and sort the rows in memory using an in-memory filesort
operation.ORDER BY
,但也存在LIMIT
子句,则优化器可以避免使用合并文件,并使用内存中的filesort
操作对内存中的行进行排序。
If multiple rows have identical values in the 如果多行在ORDER BY
columns, the server is free to return those rows in any order, and may do so differently depending on the overall execution plan. ORDER BY
列中具有相同的值,则服务器可以自由地以任何顺序返回这些行,并且根据总体执行计划的不同,返回的顺序也可能不同。In other words, the sort order of those rows is nondeterministic with respect to the nonordered columns.换句话说,这些行的排序顺序相对于非排序列是不确定的。
One factor that affects the execution plan is 影响执行计划的一个因素是LIMIT
, so an ORDER BY
query with and without LIMIT
may return rows in different orders. LIMIT
,因此有LIMIT
和无LIMIT
的ORDER BY
查询可能会以不同的顺序返回行。Consider this query, which is sorted by the 考虑此查询,该查询由category
column but nondeterministic with respect to the id
and rating
columns:category
列排序,但相对于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 |
+----+----------+--------+
Including 包含LIMIT
may affect order of rows within each category
value. LIMIT
可能会影响每个category
值中的行顺序。For example, this is a valid query result:例如,这是一个有效的查询结果:
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 |
+----+----------+--------+
In each case, the rows are sorted by the 在每种情况下,行都是按照ORDER BY
column, which is all that is required by the SQL standard.ORDER BY
列排序的,这是SQL标准所要求的全部内容。
If it is important to ensure the same row order with and without 如果重要的是确保具有LIMIT
, include additional columns in the ORDER BY
clause to make the order deterministic. LIMIT
和不具有LIMIT
的行顺序相同,请在ORDER BY
子句中包含其他列,以使顺序具有确定性。For example, if 例如,如果id
values are unique, you can make rows for a given category
value appear in id
order by sorting like this:id
值是唯一的,则可以通过如下排序使给定category
值的行按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 | +----+----------+--------+
For a query with an 对于带有ORDER BY
or GROUP BY
and a LIMIT
clause, the optimizer tries to choose an ordered index by default when it appears doing so would speed up query execution. ORDER BY
或GROUP BY
和LIMIT
子句的查询,优化器会在默认情况下尝试选择一个有序索引,因为这样做会加快查询的执行速度。Prior to MySQL 8.0.21, there was no way to override this behavior, even in cases where using some other optimization might be faster. 在MySQL 8.0.21之前,即使在使用其他优化可能更快的情况下,也无法覆盖此行为。Beginning with MySQL 8.0.21, it is possible to turn off this optimization by setting the 从MySQL 8.0.21开始,可以通过将optimizer_switch
system variable's prefer_ordering_index
flag to off
.optimizer_switch
系统变量的prefer_ordering_index
标志设置为off
来关闭此优化。
Example: First we create and populate a table 示例:首先,我们创建并填充一个表t
as shown here:t
,如下所示:
# Create and populate a table t: mysql>CREATE TABLE t (
->id1 BIGINT NOT NULL,
->id2 BIGINT NOT NULL,
->c1 VARCHAR(50) NOT NULL,
->c2 VARCHAR(50) NOT NULL,
->PRIMARY KEY (id1),
->INDEX i (id2, c1)
->);
# [Insert some rows into table t - not shown]
Verify that the 验证是否已启用prefer_ordering_index
flag is enabled:prefer_ordering_index
标志:
mysql> SELECT @@optimizer_switch LIKE '%prefer_ordering_index=on%';
+------------------------------------------------------+
| @@optimizer_switch LIKE '%prefer_ordering_index=on%' |
+------------------------------------------------------+
| 1 |
+------------------------------------------------------+
Since the following query has a 因为下面的查询有一个LIMIT
clause, we expect it to use an ordered index, if possible. LIMIT
子句,如果可能的话,我们希望它使用一个有序索引。In this case, as we can see from the 在本例中,正如我们从EXPLAIN输出中看到的,它使用表的主键。EXPLAIN
output, it uses the table's primary key.
mysql>EXPLAIN SELECT c2 FROM t
->WHERE id2 > 3
->ORDER BY id1 ASC LIMIT 2\G
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: t partitions: NULL type: index possible_keys: i key: PRIMARY key_len: 8 ref: NULL rows: 2 filtered: 70.00 Extra: Using where
Now we disable the 现在我们禁用prefer_ordering_index
flag, and re-run the same query; this time it uses the index i
(which includes the id2
column used in the WHERE
clause), and a filesort:preference_ordering_index
标志,并重新运行相同的查询;这次它使用索引i
(包括WHERE
子句中使用的id2
列)和filesort
:
mysql>SET optimizer_switch = "prefer_ordering_index=off";
mysql>EXPLAIN SELECT c2 FROM t
->WHERE id2 > 3
->ORDER BY id1 ASC LIMIT 2\G
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: t partitions: NULL type: range possible_keys: i key: i key_len: 8 ref: NULL rows: 14 filtered: 100.00 Extra: Using index condition; Using filesort
See also Section 8.9.2, “Switchable Optimizations”.另请参阅第8.9.2节,“可切换优化”。