支持的版本:当前 (17) / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

11.4. 索引和 ORDER BY #

除了简单地找到查询要返回的行之外,索引还可以按照特定的排序顺序交付它们。这使得查询的 ORDER BY 规范无需单独的排序步骤即可实现。在 PostgreSQL 当前支持的索引类型中,只有 B 树可以生成排序的输出 — 其他索引类型以未指定的、依赖于实现的顺序返回匹配的行。

规划器将考虑通过扫描与规范匹配的可用索引,或者通过按物理顺序扫描表并执行显式排序来满足 ORDER BY 规范。对于需要扫描表中很大一部分的查询,显式排序可能比使用索引更快,因为它由于遵循顺序访问模式而需要更少的磁盘 I/O。当只需要获取少量行时,索引更有用。一个重要的特殊情况是 ORDER BYLIMIT n 结合使用:显式排序将必须处理所有数据以识别前 n 行,但如果存在与 ORDER BY 匹配的索引,则可以直接检索前 n 行,而无需扫描其余部分。

默认情况下,B 树索引以升序存储其条目,空值在最后(表 TID 被视为其他相等条目之间的并列分隔列)。这意味着对列 x 的索引进行前向扫描会生成满足 ORDER BY x(或更详细地说,ORDER BY x ASC NULLS LAST)的输出。索引也可以向后扫描,生成满足 ORDER BY x DESC(或更详细地说,ORDER BY x DESC NULLS FIRST,因为 NULLS FIRSTORDER BY DESC 的默认值)的输出。

您可以通过在创建索引时包含选项 ASCDESCNULLS FIRST 和/或 NULLS LAST 来调整 B 树索引的排序;例如

CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST);
CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);

以升序存储且空值在前的索引可以满足 ORDER BY x ASC NULLS FIRSTORDER BY x DESC NULLS LAST,具体取决于扫描的方向。

您可能想知道为什么要在提供了两个选项以及反向扫描的可能性已经覆盖了 ORDER BY 的所有变体的情况下,还要提供所有四个选项。在单列索引中,这些选项确实是多余的,但在多列索引中,它们可能很有用。考虑 (x, y) 上的两列索引:如果我们向前扫描,它可以满足 ORDER BY x, y,如果我们向后扫描,它可以满足 ORDER BY x DESC, y DESC。但可能是应用程序经常需要使用 ORDER BY x ASC, y DESC。没有办法从普通索引获得该排序,但如果索引定义为 (x ASC, y DESC)(x DESC, y ASC),则可以实现。

显然,具有非默认排序的索引是一个相当专业化的功能,但有时它们可以为某些查询产生巨大的加速效果。是否值得维护这样的索引取决于您使用需要特殊排序顺序的查询的频率。

提交更正

如果您在文档中发现任何不正确、与特定功能体验不符或需要进一步澄清的内容,请使用此表格报告文档问题。