?
This document uses PHP Chinese website manual Release
一個(gè)單獨(dú)的索引掃描只能用于這樣的條件子句:使用被索引字段和索引操作符類中操作符,并且這些條件以 AND連接。 假設(shè)在(a, b)上有一個(gè)索引,那么類似 WHERE a = 5 AND b = 6 的條件可以使用索引, 但是像WHERE a = 5 OR b = 6的條件就不能直接使用索引。
幸運(yùn)的是,PostgreSQL能夠組合多個(gè)索引(包括同一索引的多次使用)來處理單個(gè)索引掃描不能實(shí)現(xiàn)的情況。 系統(tǒng)可以在多個(gè)索引掃描之間組成AND和OR條件。 比如,一個(gè)類似WHERE x = 42 OR x = 47 OR x = 53 OR x = 99這樣的查詢可以分解成四個(gè)在x上的獨(dú)立掃描, 每個(gè)掃描使用一個(gè)條件,最后將這些掃描的結(jié)果OR在一起,生成最終結(jié)果。 另外一個(gè)例子是,如果我們在x 和y上有獨(dú)立的索引,一個(gè)類似WHERE x = 5 AND y = 6這樣的查詢可以分解為幾個(gè)使用獨(dú)立索引的子句, 然后把這幾個(gè)結(jié)果AND在一起,生成最終結(jié)果。
為了組合多個(gè)索引,系統(tǒng)掃描每個(gè)需要的索引,然后在內(nèi)存里組織一個(gè)位圖,它給出索引掃描報(bào)告中符合索引條件的表數(shù)據(jù)行位置。 然后,根據(jù)查詢的需要,把這個(gè)位圖使用AND和OR合并在一起。 最后,訪問實(shí)際的表檢索并返回?cái)?shù)據(jù)行。表的數(shù)據(jù)行是按照物理順序進(jìn)行訪問的,因?yàn)槟蔷褪俏粓D的布局; 這就意味著任何原來的索引排序都將消失,而如果查詢有一個(gè) ORDER BY子句,那么還需要一個(gè)額外的排序步驟。 因?yàn)檫@個(gè)原因,以及每個(gè)額外的索引掃描都增加了額外的時(shí)間,規(guī)劃器有時(shí)候會(huì)選擇使用簡單的索引掃描,即使有多個(gè)索引可用也如此。
在所有最簡單的應(yīng)用里,可能有多種索引組合都是有用的,數(shù)據(jù)庫開發(fā)人員必須在使用哪個(gè)索引之間作出平衡。 有時(shí)候多字段索引是最好的,但有時(shí)候創(chuàng)建一個(gè)獨(dú)立索引并依靠索引組合是最好的。 比如,假如你的查詢有時(shí)候只涉及字段x,有時(shí)候只涉及字段y,有時(shí)候兩個(gè)字段都涉及, 那么你可能會(huì)選擇在 x和y上創(chuàng)建兩個(gè)獨(dú)立的索引,然后依靠索引組合來處理同時(shí)使用兩個(gè)字段的查詢。 你也可以在(x, y)上創(chuàng)建一個(gè)多字段索引,這樣索引通常會(huì)比比索引組合更高效, 但是,正如我們在Section 11.3里面討論的,它對(duì)那些只包含y的查詢幾乎沒有用,因此它不能是唯一一個(gè)索引。 一個(gè)多字段索引和y上的獨(dú)立索引可能會(huì)更好。因?yàn)閷?duì)那些只涉及x的查詢,可以使用多字段索引,盡管它會(huì)更大, 會(huì)比只在x上的索引更慢。 最后一個(gè)選擇是創(chuàng)建三個(gè)索引,但是這種方法只有在表的更新遠(yuǎn)比查詢少得多,并且所有三種查詢都很普遍的情況下才是合理的。 如果其中一種查詢比其它的少很多,那么你可能更愿意僅僅創(chuàng)建兩種匹配更常見查詢的索引。