可用版本:Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

SQL: 依赖隐式排序

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

SQL 查询产生可靠排序

例如

SELECT *
FROM BOOK
ORDER BY title, id

在上面的许多示例中,如果 RDBMS 没有产生任何隐式排序,那将是很奇怪的。但是,由于 SQL 是一种 4GL,并且优化器可以自由地生成任何实现查询规范的执行计划(该规范没有明确指定任何排序),因此您的假设可能随时会失效。

隐式行插入顺序

SELECT TITLE FROM BOOK;

您可能认为行只是简单地从表中读取,但是如果此表是一个视图怎么办?如果它是分区的怎么办?如果它是分布式的怎么办?如果覆盖索引突然应用怎么办?

隐式派生表排序

SELECT TITLE FROM (
  SELECT TITLE FROM BOOK ORDER BY TITLE
) AS B;

派生表指定了显式排序,但外部查询没有。没有什么可以阻止优化器决定在这种情况下,显式排序是不必要的,即使它不太可能因为任意原因这样做。

隐式 UNION 子查询排序

(SELECT TITLE FROM BOOK ORDER BY TITLE) UNION (SELECT 'Not really a book')

UNION 子查询指定了显式排序,但根本没有要求 UNION 运算符来维护此排序。实际上,UNION 可能使用哈希来实现,因此排序将不稳定。

隐式窗口排序

SELECT TITLE, ROW_NUMBER () OVER (ORDER BY TITLE)
FROM BOOK;

窗口函数可以排序,并且该排序可以在查询中保持稳定,这样偶然,结果会像人们期望的那样。但是,对此没有任何保证。 RDBMS 可能会以与窗口函数不同的任何其他顺序生成结果。

隐式 GROUP BY 排序

SELECT AUTHOR_ID, COUNT(*) FROM BOOK GROUP BY AUTHOR_ID;

GROUP BY 子句可以使用排序操作来实现,但也可以使用哈希来实现。不能保证使用一种算法而不是另一种算法。通过排序,可能会有一个偶然的顺序保持稳定,但是对此没有任何保证。

隐式非确定性排序

SELECT ID, TITLE FROM BOOK ORDER BY TITLE;

在我们的架构中,TITLE 不是 UNIQUE 列,因此多个书籍可能共享相同的标题。除非 ID 包含在 ORDER BY 子句中,否则不能保证结果 ID 值之间有任何稳定的排序。

反馈

您对此页面有任何反馈吗? 我们很乐意听到!

The jOOQ Logo