?
This document uses PHP Chinese website manual Release
假設(shè)有像下面這樣一個表:
CREATE TABLE test1 ( id integer, content varchar );
并且進行大量的類似下面這樣的語句進行查詢:
SELECT content FROM test1 WHERE id = constant;
通常,數(shù)據(jù)庫系統(tǒng)不得不一行一行地掃描整個test1表以尋找所有匹配的記錄。 如果在test1里面有許多行,但是只返回少數(shù)幾行(可能是零行或一行), 那么上面這個方法可就很差勁了。如果我們讓數(shù)據(jù)庫系統(tǒng)在 id列上維護一個索引用于定位匹配的行。 這樣,數(shù)據(jù)庫系統(tǒng)只需要在搜索樹中走少數(shù)的幾層就可以找到匹配行。
在大多數(shù)非小說的書籍里面都使用了類似這樣的方法: 在書的背后收集著讀者會經(jīng)常查找的術(shù)語和概念的索引,并按照字母順序排列。 有興趣的讀者可以快速地掃描該索引并且切換到合適的頁,因此不用閱讀整本書就能查找到感興趣的位置。 作者的任務(wù)之一就是預(yù)計哪些項是讀者最需要查找的東西,與之類似,預(yù)計哪些索引可以帶來便利也是數(shù)據(jù)庫程序員的任務(wù)。
下面的命令可以用于在id列上創(chuàng)建前面討論過的索引:
CREATE INDEX test1_id_index ON test1 (id);
索引名字test1_id_index可以自由選擇,但是應(yīng)該選那些稍后可以讓你回憶起索引含義的名字。
要刪除一個索引,使用DROP INDEX命令??梢栽谌魏螘r候向表里增加索引或者從表中刪除索引。
一旦你創(chuàng)建了索引,那么就不需要更多干涉了:當(dāng)該表被修改后,系統(tǒng)會自動更新索引,并且當(dāng)對表進行查詢時,如果系統(tǒng)認(rèn)為使用索引比進行順序的表掃描更有效時,系統(tǒng)會選擇使用索引進行查詢。 不過你可能必須經(jīng)常性地運行ANALYZE命令以更新統(tǒng)計信息,好讓查詢規(guī)劃器能夠做出有訓(xùn)練有素的判斷。 參見Chapter 14獲取關(guān)于如何獲知是否使用了索引的信息,以及在什么時候、什么原因下規(guī)劃器會決定不使用索引。
索引對帶搜索條件的UPDATE和DELETE命令也有好處。 索引更可以用于表鏈接查詢。因此,如果你定義了索引的列是鏈接條件的一部分,那么它可以顯著提高鏈接的查詢速度。
在一個巨大的表上創(chuàng)建索引可能會消耗大量的時間。缺省時,PostgreSQL允許在創(chuàng)建索引的同時讀取表(SELECT), 但是寫入表(INSERT, UPDATE, DELETE)的動作將被阻塞到索引創(chuàng)建完畢。在生產(chǎn)環(huán)境下這種阻塞通常是不可接受的, 因此也允許在創(chuàng)建索引的同時寫入表,但是有一些警告需要注意,更多信息參見Building Indexes Concurrently。
創(chuàng)建索引之后,它必須和表保持同步。這些操作增加了數(shù)據(jù)操作的負荷。因此我們應(yīng)該把那些非關(guān)鍵或者根本用不上的索引刪除掉。