2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 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),则可以获得。

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

提交更正

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