网上已经有很多线程,只是想了解让我感到困惑的一些细微差别!
如果将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
先排序然后排序!!?
答案 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条记录。