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 / 8.2

11.1. 引言 #

假設我們有一個如下的表

CREATE TABLE test1 (
    id integer,
    content varchar
);

並且應用程式發出許多如下形式的查詢

SELECT content FROM test1 WHERE id = constant;

在沒有任何預先準備的情況下,系統將不得不逐行掃描整個test1表,以查詢所有匹配的條目。如果test1表中有許多行,而這樣的查詢只返回少數幾行(可能為零或一行),那麼這顯然是一種效率不高的方法。但是,如果系統已被指示在id列上維護一個索引,它就可以使用一種更有效的方法來定位匹配的行。例如,它可能只需要深入搜尋樹的幾層。

大多數非虛構類書籍也採用了類似的方法:讀者經常查詢的術語和概念被收集在書末的字母索引中。感興趣的讀者可以相對快速地瀏覽索引並翻到相應的頁面,而不是閱讀整本書來查詢感興趣的內容。正如作者的任務是預見讀者可能查詢的條目一樣,資料庫程式設計師的任務也是預見哪些索引會有用。

如下命令可以用來在id列上建立索引,如前所述

CREATE INDEX test1_id_index ON test1 (id);

索引名 test1_id_index 可以自由選擇,但您應該選擇一個能夠讓您以後記住該索引用途的名稱。

要刪除索引,請使用DROP INDEX命令。索引可以隨時新增到表上或從表中刪除。

一旦建立了索引,就不需要進一步的干預了:當表被修改時,系統會自動更新索引,並且當它認為使用索引比順序表掃描更有效時,它會在查詢中使用該索引。但是,您可能需要定期執行ANALYZE命令來更新統計資訊,以便查詢規劃器能夠做出明智的決策。有關如何確定索引是否被使用以及規劃器何時以及為何可能選擇使用索引的資訊,請參閱第 14 章

索引也可以為具有搜尋條件的UPDATEDELETE命令提供幫助。此外,索引也可以用於連線搜尋。因此,在連線條件列上定義的索引也可以顯著加快帶有連線的查詢速度。

總的來說,PostgreSQL索引可用於最佳化包含一個或多個如下形式的WHEREJOIN子句的查詢

indexed-column indexable-operator comparison-value

其中,indexed-column是索引定義的任何列或表示式。indexable-operator是索引對於被索引列的運算子類的成員運算子。(更多細節將在後面介紹。)而comparison-value可以是任何非易失性且不引用索引表的表示式。

在某些情況下,查詢規劃器可以從另一個SQL構造中提取出這種形式的可索引子句。一個簡單的例子是,如果原始子句是

comparison-value operator indexed-column

那麼,如果原始operator有一個換位運算子,並且該運算子是索引的運算子類中的一個成員,則可以將其反轉為可索引的形式。

在大型表上建立索引可能需要很長時間。預設情況下,PostgreSQL允許在建立索引的同時對錶進行讀取(SELECT語句),但寫入(INSERTUPDATEDELETE)將被阻塞,直到索引構建完成。在生產環境中,這通常是不可接受的。可以允許在建立索引的同時進行寫入操作,但需要注意幾個注意事項——有關更多資訊,請參閱併發構建索引

建立索引後,系統必須將其與表保持同步。這會增加資料操作操作的開銷。索引也可能阻止僅堆元組 (HOT)的建立。因此,在查詢中很少或從不使用的索引應該被刪除。

提交更正

如果您在文件中看到任何不正確、與您對特定功能的體驗不符或需要進一步說明的內容,請使用此表單報告文件問題。