我正在负载下测试我的数据库设计,我只需要检索固定数量的行(5000)
我可以指定一个 LIMIT 来实现这一点,但似乎查询构建了所有匹配行的结果集,然后只返回限制中指定的行数。是这样实现的吗?
MySQL 是否可以读取一行,读取另一行并在检索到第 5000 个匹配行时基本停止?
MySQL 的聪明之处在于,如果您LIMIT 5000
在查询中指定 a,并且可以在不首先生成整个结果集的情况下生成该结果,那么它将不会构建整个结果。
例如,以下查询:
SELECT * FROM table ORDER BY column LIMIT 5000
这个查询需要扫描整个table
,除非有一个索引column
,在这种情况下,它会做聪明的事情,并使用索引来查找最小的行column
。
SELECT * FROM `your_table` LIMIT 0, 5000
这将显示数据库中的前 5000 个结果。
SELECT * FROM `your_table` LIMIT 1001, 5000
这将显示从 1001 到 6000 的记录(从 0 开始计数)。
此类查询的复杂性为 O(LIMIT)(除非您指定 order by)。
这意味着如果 10000000 行将匹配您的查询,并且您指定的限制等于 5000,那么复杂度将为 O(5000)。
@Jarosław Gomułka 是对的
如果您将 LIMIT 与 ORDER BY 一起使用,MySQL 会在找到排序结果的前 row_count 行后立即结束排序,而不是对整个结果进行排序。如果使用索引进行排序,则速度非常快。在任何一种情况下,在找到初始行之后,都不需要对结果集的任何剩余部分进行排序,MySQL 也不会这样做。如果该集合未排序,则一旦结果集有足够的行,它就会终止 SELECT 操作。
查询优化器使用的确切计划取决于您的查询(选择了哪些字段、LIMIT 数量以及是否有 ORDER BY)和您的表(键、索引和表中的行数)。选择未索引的列和/或按非键列排序将产生与选择列和按主键列排序不同的执行计划。后者甚至不会触及表格,而只会处理您的 LIMIT 中指定的行数。
每个数据库都定义了自己的限制结果集大小的方法,具体取决于您使用的数据库。
虽然 SQL:2008 规范定义了限制 SQL 查询的标准语法,但 MySQL 8 不支持它。
因此,在 MySQL 上,您需要使用该LIMIT
子句将结果集限制为 Top-N 记录:
SELECT
title
FROM
post
ORDER BY
id DESC
LIMIT 50
请注意,我们使用的是 ORDER BY 子句,否则无法保证返回结果集中包含的第一条记录。