深入探討DB2表連接原理
DB2表連接操作是我們經(jīng)??梢砸姷降模挛膶?a >DB2表連接原理作了詳盡的闡述分析,如果您對此方面感興趣的話,不妨一看。
在DB2中,優(yōu)化器可以選擇嵌套連接或合并連接,如果得到正確支持的話,還可以選擇散列連接。如果系統(tǒng)調(diào)優(yōu)得正確,散列連接可顯著提高某些查詢的性能。DB2優(yōu)化器可以在執(zhí)行連接時(shí)選擇不同方法:在缺省情況下,它在嵌套循環(huán)連接(nested loop join)與合并連接(merge join)之間選擇。當(dāng)設(shè)置了特殊環(huán)境變量時(shí),它還可以選擇散列連接(hash join)。
兩個(gè)表之間的連接是這樣操作的:將一個(gè)表中的行與另一個(gè)表中的行并置在一起。另外,可以指定條件以定義并置哪些行。為執(zhí)行這一操作,DB2 可以選擇不同的連接方法。在連接兩個(gè)表時(shí),無論使用哪種連接方法,總有一個(gè)表被選為外表(outer table)而另一個(gè)表被選為內(nèi)表(inner table)。優(yōu)化器根據(jù)所選連接方法的成本和類型決定哪個(gè)是外表、哪個(gè)是內(nèi)表。首先訪問外表,并且只掃描一次。根據(jù)連接的類型和存在的索引,可以多次掃描內(nèi)表。還有一點(diǎn)也很重要,要記住即使您試圖連接兩個(gè)以上的表,優(yōu)化器也將每次只連接兩個(gè)表,并在必要時(shí)保存中間結(jié)果。要理解散列連接方法的優(yōu)勢,先理解其它連接方法的工作原理也很重要。
嵌套循環(huán)連接
正如我們前面提到的那樣,外表只被掃描一次。對于嵌套循環(huán)連接,要在內(nèi)表中找到與外表中每一行相匹配的行有兩種方法:
掃描內(nèi)表。即,讀取內(nèi)表中的每一行,并且針對該行決定是否應(yīng)將其與正在考慮的外表中的行相連接。
對內(nèi)表上的連接列進(jìn)行索引查找。當(dāng)用于連接的謂詞所包含的列在內(nèi)表的索引中時(shí),這種方法是可行的。這極大地減少了在內(nèi)表中訪問的行數(shù)。
在嵌套循環(huán)連接中,決定哪個(gè)是外表、哪個(gè)是內(nèi)表非常重要,因?yàn)橥獗碇粧呙枰淮?,而針對外表中的每一行,都要訪問一次內(nèi)表。正如前面提到的那樣,優(yōu)化器用成本模型來決定誰是外表誰是內(nèi)表。優(yōu)化器做此決定時(shí)會(huì)考慮幾個(gè)因素:
表的大小
緩沖
謂詞
排序要求
是否存在索引
連接列不能是 LONG 或 LOB 字段。
合并連接
合并連接需要一個(gè)等式連接謂詞(即具有 table1.column = table2.column 格式的謂詞)。它還要求根據(jù)連接列對輸入表進(jìn)行排序。通過掃描現(xiàn)有索引或在進(jìn)行連接之前對表進(jìn)行排序就可以做到這一點(diǎn)。連接列不能是 LONG 或 LOB 字段。
同時(shí)掃描兩個(gè)表,以查找匹配行。外表和內(nèi)表都只掃描一次,除非外表中有重復(fù)的值,那樣的話可能要再次掃描內(nèi)表的某些部分。因?yàn)楸硗ǔV槐粧呙枰淮?,所以決定哪個(gè)是外表、哪個(gè)是內(nèi)表不象在其它連接方法中那么重要。盡管如此,由于可能有重復(fù)的值,所以優(yōu)化器通常選擇重復(fù)值較少的表作為外表。但是,優(yōu)化器最終還是使用成本模型來決定誰是外表誰是內(nèi)表。
散列連接
散列連接需要一個(gè)或多個(gè)等式連接謂詞,其中每個(gè)謂詞的列類型相同。就 CHAR 類型而言,長度必須相同。就 DECIMAL 類型而言,精度和小數(shù)位必須相同。同樣,連接列不能是 LONG 或 LOB 字段。散列連接可處理多個(gè)等式謂詞這一事實(shí)相對于合并連接是一大優(yōu)勢,后者只能處理一個(gè)等式謂詞。
對于散列連接,首先掃描內(nèi)表(也稱為構(gòu)建表,bulid table),表中的行被復(fù)制到內(nèi)存緩沖區(qū)。根據(jù)“散列代碼(hash code)”,這些緩沖區(qū)被分為幾個(gè)分區(qū),散列代碼是根據(jù)連接謂詞中的列計(jì)算出來的。如果內(nèi)存中沒有足夠的空間容納整個(gè)表,則有些分區(qū)被寫入磁盤上的臨時(shí)表。然后掃描外表(稱為探測表,probe table)。對于探測表中的每一行,對連接列應(yīng)用同一散列算法。如果所獲得的散列代碼與構(gòu)建行的散列代碼相匹配,則比較實(shí)際的連接列。如果與探測表行匹配的分區(qū)在內(nèi)存中,則比較會(huì)立即進(jìn)行。如果分區(qū)被寫入臨時(shí)表,則探測行也被寫入臨時(shí)表。最后,處理包含同一分區(qū)中的行的臨時(shí)表以進(jìn)行匹配。
由于將構(gòu)建表保存在內(nèi)存中所具有的好處,優(yōu)化器通常選擇較小的表作為構(gòu)建表,以避免必須將該表溢出(spill)到磁盤上。但是,要再次強(qiáng)調(diào)的是,成本模型最終決定哪個(gè)表是內(nèi)表、哪個(gè)表是外表。
選擇哪種連接方法?
到目前為止,我們已經(jīng)討論了在DB2中可用的不同連接方法。正如我們所知,初看起來,某些方法與其它方法相比是更好的選擇。例如,與根據(jù)外表的每一行掃描內(nèi)表的嵌套循環(huán)連接相比,合并連接具有只對表掃描一次的優(yōu)勢。于是,合并連接似乎是一個(gè)更好的選擇;但是,如果存在索引的話,則嵌套循環(huán)會(huì)是更好的選擇。
同樣地,與合并連接相比,散列連接似乎是更好的選擇,因?yàn)樗恍枰趫?zhí)行前對輸入表排序,但如果我們需要保持外表中行的次序,則合并連接或嵌套循環(huán)連接可能是更好的選擇 — 散列連接不能保證維持次序,因?yàn)樗赡芤绯龅酱疟P而那樣會(huì)破壞次序。
【編輯推薦】
DB2創(chuàng)建數(shù)據(jù)庫的實(shí)現(xiàn)




















