2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 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-tree 能夠產生排序輸出——其他索引型別返回匹配的行時,順序是不確定的、依賴於實現的。

查詢規劃器會考慮透過掃描匹配該規範的可用索引,或者透過按物理順序掃描表並執行顯式排序來滿足 ORDER BY 規範。對於需要掃描表中大部分行的情況,顯式排序可能比使用索引更快,因為它由於順序訪問模式而需要的磁碟 I/O 更少。當只需要獲取少量行時,索引更有用。一個重要的特殊情況是 ORDER BYLIMIT n 結合使用:顯式排序需要處理所有資料來確定前 n 行,但如果存在匹配 ORDER BY 的索引,則可以直接檢索前 n 行,而無需掃描剩餘的部分。

預設情況下,B-tree 索引按升序儲存其條目,NULL 值排在最後(在條目相等的情況下,表 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-tree 索引的排序順序;例如:

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

以升序儲存且 NULL 值排在前面的索引,根據掃描方向的不同,可以滿足 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),則可以實現。

顯然,具有非預設排序順序的索引是一種相當特殊的特性,但有時它們可以為某些查詢帶來巨大的速度提升。維護這樣一個索引是否值得,取決於您使用需要特殊排序順序的查詢的頻率。

提交更正

如果您在文件中發現任何不正確之處、與您在使用該特定功能時的經驗不符之處,或者需要進一步說明之處,請使用 此表單 來報告文件問題。