🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 11.4\. 索引和`ORDER BY` 除了只是返回查询到的行,索引可以以一个特定的顺序传送它们。这样就允许查询的`ORDER BY` 说明可以不用一个单独的排序步骤。当前PostgreSQL支持的索引类型, 只有 B-tree 可以产生排序的输出—其他的索引类型返回的行是非指定的、依赖于实现的顺序。 规划器将考虑满足`ORDER BY`声明,通过扫描匹配声明的可用的索引, 或者通过扫描物理顺序的表和做一个明确的排序。对于一个需要扫描表的一大部分的查询, 明确的排序可能要比使用索引快的多,因为它使用顺序存取模式所以需要较少的磁盘I/O。 当只需要获取几行时,索引是更有效的。一个重要的特殊情况是`ORDER BY`和 `LIMIT` `_n_`一起使用:一个明确的排序将处理所有的数据以识别前 `_n_`行,但是如果有一个索引匹配`ORDER BY`,那么前`_n_` 行可以直接找出,而不用扫描剩下的部分。 默认的,B-tree索引以递增、空值最后的顺序存储记录。这意味着在字段`x` 上向前扫描索引产生的输出满足`ORDER BY x`(或者`ORDER BY x ASC NULLS LAST`)。 索引扫描也可以向后扫描,产生的输出满足`ORDER BY x DESC`(或者 `ORDER BY x DESC NULLS FIRST`,因为`NULLS FIRST`默认是`ORDER BY DESC`)。 创建索引时,可以通过包含选项`ASC`, `DESC`, `NULLS FIRST`, 和/或 `NULLS LAST`调整B-tree索引的顺序;例如: ``` 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 FIRST`或 `ORDER 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)`就是可能的了。 明显的,没有默认排序顺序的索引是比较专业的特征,但是有时它们对特定的查询可以产生极大的加速。 是否值得维持这样的索引取决于你使用需要特殊排序顺序的查询的频率。