讓你的連接查詢加速
Posted on 2005-02-03 21:00 海天一鷗 閱讀(174) 評(píng)論(0) 編輯 收藏 所屬分類: Java數(shù)據(jù)庫(kù)技術(shù)Oracle9i引入了一種新的方法來(lái)加速對(duì)大型數(shù)據(jù)倉(cāng)表格的連接(join)查詢。這種新的方法,即位圖連接索引(bitmap join index),要求創(chuàng)建一個(gè)索引,有這個(gè)索引在它被創(chuàng)建的時(shí)候進(jìn)行合并操作,然后為連接中用到的關(guān)鍵字創(chuàng)建一個(gè)位圖索引。
|
位圖連接索引背后的技術(shù)其實(shí)是把低基數(shù)數(shù)據(jù)列預(yù)先連接在一起,這樣就讓整體的連接(操作)進(jìn)行得更快。在本文的例子里,我們將使用一個(gè)零件和供應(yīng)商之間的多對(duì)多關(guān)系。每個(gè)零件都由多個(gè)供應(yīng)商供應(yīng),而每個(gè)供應(yīng)商能夠提供多種零件。這個(gè)數(shù)據(jù)庫(kù)里有200種不同類型的零件,供應(yīng)商可以在(美國(guó))所有50個(gè)州供應(yīng)零件。
要?jiǎng)?chuàng)建一個(gè)位圖連接索引,我們要使用下面的SQL。要注意CREATE INDEX句法里的FROM和WHERE子句。
create bitmap index
part_suppliers_state
on
inventory( parts.part_type, supplier.state)
from
inventory i,
parts p,
supplier s
where
i.part_id = p.part_id
and
i.supplier_id = p.part_id;
盡管b-tree索引被用在標(biāo)準(zhǔn)的交叉記錄(junction record)里,但是我們能夠提高Oracle9i查詢的性能,在這些查詢里判斷述詞(predicate)會(huì)用到低基數(shù)數(shù)據(jù)列。例如,看看下面的查詢,我們可以通過(guò)這個(gè)查詢來(lái)獲得北卡羅來(lái)納的所有火花塞供應(yīng)商:
select
supplier_name
from
parts
natural join
inventory
natural join
suppliers
where
part_type = 'piston'
and
state = 'nc'
;
在Oracle9i之前的版本里,這個(gè)查詢會(huì)需要一個(gè)對(duì)所有三個(gè)表格進(jìn)行嵌套循環(huán)連接(nested loop join)或者散列連接(hash join)。而在Oracle9i里,我們可以根據(jù)低基數(shù)數(shù)據(jù)列將這三個(gè)表格預(yù)先連接。
Oracle宣稱,當(dāng)所有的查詢數(shù)據(jù)都駐留在索引之內(nèi)的時(shí)候,使用這種索引方法能夠把表格連接的速度提高7倍以上。然而在很多情況下,傳統(tǒng)的散列連接或者嵌套循環(huán)連接可能會(huì)比位圖連接做得更好。
位圖連接不是一副萬(wàn)能藥。下面就是索引的一些局限性:
- 被索引的數(shù)據(jù)列必須是低基數(shù)的——通常要少于300個(gè)完全不同的值。
- 在WHERE子句里,查詢絕對(duì)不能索引哪些沒(méi)有包含在索引里的數(shù)據(jù)列。
- 更新位圖連接索引所需要的代價(jià)是相當(dāng)高的。從實(shí)用的角度講,位圖連接索引被拋棄,而在每天晚上進(jìn)行每日批量加載任務(wù)的時(shí)候才被重建。只有對(duì)于那些在處理的時(shí)候保持只讀的Oracle數(shù)據(jù)倉(cāng),位圖連接索引才會(huì)起作用。
總而言之,位圖連接索引會(huì)極大地提高特定數(shù)據(jù)倉(cāng)查詢的速度,但是其代價(jià)是在為圖索引創(chuàng)建的時(shí)候,需要預(yù)先連接表格。