假設我們有一個類似這樣的表格
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 章。
索引也可以使帶有搜尋條件的 UPDATE
和 DELETE
命令受益。此外,索引可用於連線搜尋。因此,在連線條件的一部分的欄位上定義的索引也可以顯著加速帶有連線的查詢。
一般來說,PostgreSQL 索引可用於最佳化包含一個或多個以下形式的 WHERE
或 JOIN
子句的查詢
indexed-column
indexable-operator
comparison-value
在這裡,indexed-column
是索引已定義的任何欄位或表達式。indexable-operator
是一個屬於索引欄位的 運算符類別 的運算符。(有關更多詳細信息,請參閱下文。)並且 comparison-value
可以是不易變且不引用索引表格的任何表達式。
在某些情況下,查詢規劃器可以從另一個 SQL 結構中提取這種形式的可索引子句。一個簡單的例子是,如果原始子句是
comparison-value
operator
indexed-column
那麼如果原始的 operator
具有一個屬於索引運算符類別的交換運算符,則它可以翻轉成可索引的形式。
在大型表格上建立索引可能需要很長時間。預設情況下,PostgreSQL 允許在建立索引的同時,表格上發生讀取(SELECT
語句),但寫入(INSERT
、UPDATE
、DELETE
)會被阻止,直到索引建立完成。在生產環境中,這通常是不可接受的。可以允許在建立索引的同時發生寫入,但需要注意幾個注意事項——有關更多資訊,請參閱並行建立索引。
建立索引後,系統必須使其與表格保持同步。這會增加資料操作操作的額外負荷。索引也可能阻止僅堆積元組的建立。因此,應該移除很少或從未使用過的索引。
如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步說明的地方,請使用此表格報告文件問題。