首页 文章

在SQL中按顺序执行/限制执行

提问于
浏览
0

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

Quoting the doc reference

如果将LIMIT row_count与ORDER BY结合使用,MySQL会在找到排序结果的第一行row_count行后立即停止排序,而不是对整个结果进行排序 . 如果使用索引完成排序,则速度非常快 .

and a 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 回答

  • 1

    一旦找到排序结果的第一行row_count行,MySQL就会停止排序,而不是对整个结果进行排序

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

    如果order by是在索引列上完成的,那么mysql可以很快地告诉它是否找到了前n个记录 .

  • 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 ,并在测试成功时将 article 添加到结果集中 . 当结果集中有20行时,它将停止并返回它 .

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

    如果两列都没有编入索引,它将执行全表扫描以测试 last_read_date ,对与条件匹配的所有行进行排序,并返回此前20行 .

相关问题