ORDER BY
#除了簡單地查詢查詢要返回的行之外,索引還可以按特定的排序順序返回這些行。這使得查詢的 ORDER BY
規範可以在不進行單獨排序步驟的情況下得到滿足。在 PostgreSQL 當前支援的索引型別中,只有 B-tree 能夠產生排序輸出——其他索引型別返回匹配的行時,順序是不確定的、依賴於實現的。
查詢規劃器會考慮透過掃描匹配該規範的可用索引,或者透過按物理順序掃描表並執行顯式排序來滿足 ORDER BY
規範。對於需要掃描表中大部分行的情況,顯式排序可能比使用索引更快,因為它由於順序訪問模式而需要的磁碟 I/O 更少。當只需要獲取少量行時,索引更有用。一個重要的特殊情況是 ORDER BY
與 LIMIT
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 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);
以升序儲存且 NULL 值排在前面的索引,根據掃描方向的不同,可以滿足 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)
,則可以實現。
顯然,具有非預設排序順序的索引是一種相當特殊的特性,但有時它們可以為某些查詢帶來巨大的速度提升。維護這樣一個索引是否值得,取決於您使用需要特殊排序順序的查詢的頻率。
如果您在文件中發現任何不正確之處、與您在使用該特定功能時的經驗不符之處,或者需要進一步說明之處,請使用 此表單 來報告文件問題。