ORDER BY
#除了單純地找到查詢要傳回的列之外,索引也可能能夠以特定的排序順序傳遞它們。 這允許查詢的 ORDER BY
規範在沒有單獨排序步驟的情況下得到遵守。 在 PostgreSQL 目前支援的索引類型中,只有 B-tree 可以產生排序後的輸出 — 其他索引類型以未指定的、與實作相關的順序傳回匹配的列。
規劃器會考慮透過掃描符合規範的可用索引,或透過以實體順序掃描表並執行明確排序來滿足 ORDER BY
規範。 對於需要掃描表中很大一部分的查詢,明確排序可能比使用索引更快,因為由於遵循循序存取模式,它需要的磁碟 I/O 更少。 當只需要提取少數列時,索引更有用。 一個重要的特殊情況是 ORDER BY
與 LIMIT
n
結合使用:明確排序將需要處理所有資料以識別前 n
列,但如果存在與 ORDER BY
匹配的索引,則可以直接檢索前 n
列,而無需掃描其餘部分。
預設情況下,B-tree 索引以遞增順序儲存其條目,空值排在最後(在其他相等條目中,表 TID 被視為決勝欄位)。 這表示對欄位 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)
,則這是可能的。
顯然,具有非預設排序順序的索引是一種相當專業的功能,但有時它們可以為某些查詢產生巨大的加速效果。 維護這樣的索引是否值得取決於您使用需要特殊排序順序的查詢的頻率。
如果您在文件中發現任何不正確、與特定功能的經驗不符或需要進一步澄清的地方,請使用 此表單 報告文件問題。