# 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 章](https://docs.postgresql.tw/12/the-sql-language/performance-tips)。

索引還可以使用搜索條件使 UPDATE 和 DELETE 指令受益。此外，索引可用於交叉查詢。因此，在作為交叉查詢條件一部分的欄位上定義的索引也可以顯著加快交叉查詢。

在大型資料表上建立索引可能需要很長時間。預設情況下，PostgreSQL 允許在索引建立的同時在資料表上進行讀取（SELECT 語句），但寫入（INSERT，UPDATE，DELETE）將被阻止，直到索引建構完成。在産品環境中，這通常是不可接受的。允許寫入與索引建立同時發生是可能的，但有幾點值得注意 - 有關更多訊息，請參閱[同步建立索引](https://docs.postgresql.tw/12/reference/sql-commands/create-index#building-indexes-concurrently)。

建立索引後，系統必須使其與資料表保持同步。這增加了資料操作的開銷。因此，應移除在查詢中很少或從不使用的索引。
