在SQL中按/限制执行顺序

时间:2018-12-08 20:58:08

标签: mysql sql-order-by limit

网上已经有很多线程,只是想了解让我感到困惑的一些细微差别!

引用doc reference

  

如果将LIMIT row_count与ORDER BY结合使用,MySQL将停止排序为   一旦找到排序结果的前row_count行,   而不是对整个结果进行排序。如果订购是通过使用   索引,这非常快。

和一个SO thread

  

它将首先订购,然后获得前20。数据库也将   在ORDER BY之前处理WHERE子句中的任何内容。

对问题进行相同的查询:

SELECT article
FROM table1
ORDER BY publish_date
LIMIT 20

让我们说表有2000行,其中query预计将返回20行,现在,看着 mysql ref ....stops sorting as soon as it has found the first row_count rows....使我感到困惑,因为我发现它有点含糊!!

为什么说stops sorting?不是将limit子句应用于通过order by子句返回的已排序数据(假定其为non-indexed),还是我的理解错误和SQL是limit先排序然后排序!!?

2 个答案:

答案 0 :(得分:1)

文档中提到的优化通常仅在publish_date列上有索引的情况下才有效。这些值按顺序存储在索引中,因此引擎只需遍历该列的索引,即可获取关联的行,直到获取20行为止。

如果未对列进行索引,则引擎通常需要获取所有行,对它们进行排序,然后返回其中的前20行。

了解它与WHERE条件如何相互作用也很有用。假设查询为:

SELECT article
FROM table1
WHERE last_read_date > '2018-11-01'
ORDER BY publish_date
LIMIT 20

如果publish_date被索引而last_read_date没有被索引,它将按顺序扫描publish_date索引,针对条件测试关联的last_read_date并添加{{1如果测试成功,则返回结果集。当结果集中有20行时,它将停止并返回。

如果对article进行了索引而没有对last_read_date进行索引,则它将使用publish_date索引来查找满足条件的所有行的子集。然后,它将使用last_read_date列对这些行进行排序,并从中返回前20行。

如果两个索引都没有索引,它将进行全表扫描以测试publish_date,对所有符合条件的行进行排序,然后返回该行的前20行。

答案 1 :(得分:1)

  

MySQL在找到排序结果的前row_count行后立即停止排序,而不是对整个结果进行排序

这实际上是mysql中非常明智的优化。如果您使用limit返回20行,而mysql知道已经找到了它们,那么mysql(或您)为什么会关心其余记录的排序方式呢?没关系,因此mysql停止对其余行进行排序。

如果排序依据是在索引列上完成的,那么mysql可以很迅速地判断出是否找到了前n条记录。