iT邦幫忙

2025 iThome 鐵人賽

DAY 6
3

https://ithelp.ithome.com.tw/upload/images/20250901/20177885wxRQzikYcn.png

在 PostgreSQL 中,B-Tree Index 不僅能加快搜尋速度,還能提升 ORDER BY 查詢的效率。在預設情況下,B-Tree 會以升序(ascending) 的順序儲存,並將 NULL 值放在最後(NULLS LAST)。

那麼如果查詢的 ORDER BY 需求剛好符合 Index 的排序方式,資料庫就能直接使用 Index 順序來產生排序結果,少掉額外的排序步驟,加速查詢的速度!

根據官方文件的說明:

In addition to simply finding the rows to be returned by a query, an index may be able to deliver them in a specific sorted order. This allows a query's ORDER BY specification to be honored without a separate sorting step.

預設情況下,B-Tree Index 會將欄位值按照升序(ascending)排序,NULL 值則位於最後。所以對 Index 欄位進行前向掃描(forward scan)時,會自動符合 ORDER BY x ASC NULLS LAST 的要求。

By default, B-tree indexes store their entries in ascending order with nulls last (table TID is treated as a tiebreaker column among otherwise equal entries). This means that a forward scan of an index on column x produces output satisfying ORDER BY x (or more verbosely, ORDER BY x ASC NULLS LAST).

那我們就來做個小測試,驗證上面的敘述是不是真的吧!

驗證 ORDER BY 效果

這裡一樣用 quizzes 這張表來做實驗,假設我們需要根據 subject 欄位來排序題庫。先將我們前面設定的 Index 刪除:

DROP INDEX IF EXISTS idx_quizzes_school_subject_chapter;

我們單獨把 subject 欄位建立 Index:

CREATE INDEX idx_quizzes_subject ON quizzes (subject);

接下來就來看如果使用 order by subject 來查詢,是否會使用到 Index 加速查詢呢?

EXPLAIN ANALYZE
SELECT * FROM quizzes ORDER BY subject;

https://ithelp.ithome.com.tw/upload/images/20250807/20177885ldaXLuszuw.png

這邊可以看到 Index Scan,表示 PostgreSQL 直接利用 Index 來輸出排序後的結果,避免了額外的排序。

反向排序(DESC)

假設我們今天想要查詢的資料是反向排序(desending),這樣也能用到 Index 嗎?

EXPLAIN ANALYZE
SELECT * FROM quizzes ORDER BY subject DESC;

https://ithelp.ithome.com.tw/upload/images/20250807/20177885QTJrXI6qkq.png

答案是會的!這裡可以看到 Index Scan Backward,代表資料庫直接反向讀取 B-Tree,而不需要額外的排序操作。

The index can also be scanned backward, producing output satisfying ORDER BY x DESC (or more verbosely, ORDER BY x DESC NULLS FIRST, since NULLS FIRST is the default for ORDER BY DESC). An index stored in ascending order with nulls first can satisfy either ORDER BY x ASC NULLS FIRST or ORDER BY x DESC NULLS

ORDER BY + LIMIT:加速 Top-N 查詢

官方文件有特別提到,Index 特別適用於 ORDER BY ... LIMIT n 查詢,因為它可以讓資料庫直接取得前 n 筆資料,而不需要掃描完整 table。

Indexes are more useful when only a few rows need be fetched.

An important special case is ORDER BY in combination with LIMIT n: an explicit sort will have to process all the data to identify the first n rows, but if there is an index matching the ORDER BY, the first n rows can be retrieved directly, without scanning the remainder at all.

所以如果 ORDER BY 條件與 Index 相符,PostgreSQL 可以直接利用 Index 排序,特別是在搭配 LIMIT n 時,因為他只要讀取前 n 筆資料之後就結束,剩餘的資料不需要再讀取,效能提升會更明顯。

重點回顧

  • Index 可以加速 ORDER BY 查詢:如果 ORDER BY 條件與 Index 順序一致,PostgreSQL 可以省略掉額外的排序步驟,讓查詢速度更快。
  • Index 支援反向排序(Index Scan Backward):即使 ORDER BY 使用 DESC,PostgreSQL 也可以透過反向掃描來產生結果。
  • ORDER BY + LIMIT:Index 可以讓 PostgreSQL 直接查詢前 n 筆資料,而不需要先對所有資料排序,大幅減少查詢時間。

參考資料

https://www.postgresql.org/docs/current/indexes-ordering.html


上一篇
Day 5 - Index Scan 與 Bitmap Scan
下一篇
Day 7 - UNIQUE Index:確保資料唯一性
系列文
PostgreSQL 效能優化 30 天挑戰:從 Index 到 Transaction 的深入探索8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言