表之間的連線
表的連線是指在乙個sql語句中通過表與表之間的關聯,從乙個或多個表檢索出相關的資料。連線是通過sql語句中from從句的多個表名,以及where從句裡定義的表之間的連線條件來實現的。如果乙個sql語句的關聯表超過兩個,那麼連線的順序如何呢?oracle首先連線其中的兩個表,產生乙個結果集;然後將產生的結果集與下乙個表再進行關聯;繼續這個過程,直到所有的表都連線完成;最後產生所需的資料。主要包括:a)排序合併連線;b)巢狀迴圈連線;c)雜湊連線;d)笛卡爾積連線。 a)
排序合併連線 1)
判斷第乙個源表是否已經排序,如果已經排序,則轉3),否則轉2); 2)
對第乙個源表按照連線關聯列進行排序; 3)
判斷第二個源表是否已經排序,如果已經排序,則轉5),否則轉4); 4)
對第二個源表按照連線關聯列進行排序; 5)
對已經排好序的兩個源表進行合併操作,並生成最終的結果集。
在缺乏資料的選擇性或者可用的索引時,或者兩個源表都過於龐大(所選的資料超過表記錄數的5%)時,排序合併連線將比巢狀迴圈連線更加高效。但是排序合併連線需要較大的臨時記憶體塊,以用於排序,這將導致臨時表空間占用更多的記憶體和磁碟i/o。
b)巢狀迴圈連線 1)
首先根據基於規則rbo或者基於代價cbo的原則,選擇兩個表中的乙個作為驅動表(外部表)。 2)
指定另外乙個表為內部表。 3)
從外部表中讀取第一行,然後與內部表的資料逐一進行對比,將匹配的記錄放到結果集中。 4)
從外部表中讀取第二行,再與內部表的資料逐一對比,將匹配的記錄新增到結果集中。 5)
重複上述步驟,直到外部表中的所有記錄全部處理完畢。 6)
最後產生滿足要求的結果集。
使用巢狀迴圈連線是一種從結果集中提取第一批記錄最快速的方法。在驅動行源表(就是正在查詢的記錄)較小、或者內部行源表已連線的列有惟一的索引或高度可選的非惟一索引時,巢狀迴圈連線效果是比較理想的。巢狀迴圈連線比其他連線方法有優勢,它可以快速地從結果集中提取第一批記錄,而不用等待整個結果集完全確定下來。這樣,在理想情況下,終端使用者就可以通過查詢螢幕檢視第一批記錄,而在同時讀取其他記錄。不管如何定義連線的條件或者模式,任何兩行記錄源可以使用巢狀迴圈連線,所以巢狀迴圈連線是非常靈活的。
然而,如果內部行源表(讀取的第二張表)已連線的列上不包含索引,或者索引不是高度可選時,巢狀迴圈連線效率是很低的。如果驅動表的記錄非常龐大時,其他的連線方法可能更加有效。 c)
雜湊連線
當記憶體能夠提供足夠的空間時,雜湊(hash)連線是oracle優化器通常的選擇。雜湊連線中,優化器根據統計資訊,首先選擇兩個表中的小表,在記憶體中建立這張表的基於連線鍵的雜湊表;優化器再掃瞄表連線中的大表,將大表中的資料與雜湊表進行比較,如果有相關聯的資料,則將資料新增到結果集中。
當表連線中的小表能夠完全cache到可用記憶體的時候,雜湊連線的效果最佳。雜湊連線的成本只是兩個表從硬碟讀入到記憶體的成本。但是,如果雜湊表過大而不能全部cache到可用記憶體時,優化器將會把雜湊表分成多個分割槽,再將分割槽逐一cache到記憶體中。當表的分割槽超過了可用記憶體時,分割槽的部分資料就會臨時地寫到磁碟上的臨時表空間上。因此,分割槽的資料寫磁碟時,比較大的區間(extent)會提高i/o效能。oracle推薦的臨時表空間的區間是1mb。臨時表空間的區間大小由uniform. size指定。
當雜湊表構建完成後,進行下面的處理: 1)
第二個大表進行掃瞄 2)
如果大表不能完全cache到可用記憶體的時候,大表同樣會分成很多分割槽 3)
大表的第乙個分割槽cache到記憶體 4)
對大表第乙個分割槽的資料進行掃瞄,並與雜湊表進行比較,如果有匹配的紀錄,新增到結果集裡面 5)
與第乙個分割槽一樣,其它的分割槽也類似處理。 6)
所有的分割槽處理完後,oracle對產生的結果集進行歸併,彙總,產生最終的結果。
當雜湊表過大或可用記憶體有限,雜湊表不能完全cache到記憶體。隨著滿足連線條件的結果集的增加,可用記憶體會隨之下降,這時已經cache到記憶體的資料可能會重新寫回到硬碟去。如果出現這種情況,系統的效能就會下降。
當連線的兩個表是用等值連線並且表的資料量比較大時,優化器才可能採用雜湊連線。雜湊連線是基於cbo的。只有在資料庫初始化引數hash_join_enabled設為true,並且為引數pga_aggregate_target設定了乙個足夠大的值的時候,oracle才會使用雜湊邊連線。hash_area_size是向下相容的引數,但在oracle9i之前的版本中應當使用hash_area_size。當使用ordered提示時,from子句中的第一張表將用於建立雜湊表。
當缺少有用的索引時,雜湊連線比巢狀迴圈連線更加有效。雜湊連線也可能比巢狀迴圈連線更快,因為處理記憶體中的雜湊錶比檢索b_樹索引更加迅速。
d)笛卡爾積連線
當兩張表進行連線,它們之間沒有任何關聯條件時,這兩張表就會進行笛卡爾乘積連線。笛卡爾乘積連線是使用乙個表的每一行依次與另乙個表中的所有行匹配。例如:表a和表b做笛卡爾乘積連線,表a有m行記錄,表b有n 行記錄,則笛卡爾乘積的結果為m*n條記錄。
三種連線方式的比較:
類別 巢狀迴圈連線
排序合併連線
雜湊連線
優化器提示
use_nl
use_merge
use_hash
使用的條件
任何連線
主要用於不等價連線,如<、<=、>、>=;
但是不包括<>
僅用於等價連線
相關資源
cpu、磁碟i/o
記憶體、臨時空間
記憶體、臨時空間 特點
當有高選擇性索引或進行限制性搜尋時效率比較高,能夠快速返回第一次的搜尋結果。
當缺乏索引或者索引條件模糊時,排序合併連線比巢狀迴圈有效。
當缺乏索引或者索引條件模糊時,雜湊連線連線比巢狀迴圈有效。通常比排序合併連線快。
在資料倉儲環境下,如果表的紀錄數多,效率高。 缺點
當索引丟失或者查詢條件限制不夠時,效率很低;
當表的紀錄數多時,效率低。
所有的表都需要排序。它為最優化的吞吐量而設計,並且在結果沒有全部找到前不返回資料。
為建立雜湊表,需要大量記憶體。第一次的結果返回較慢。
ArcEngine dbf表之間連線Join
arcengine dbf表之間連線join 上乙個部落格寫了要素圖層屬性表與.dbf之間的連線join,但是若想兩個.dbf表之間連線,再用那種方法就不行了,因此這裡呼叫gp工具實現.dbf表之間的連線join。gp工具實在是強大,能解決你的問題,但是卻不能讓你知道到底如何實現的,連線之後開啟.d...
論表與表之間的關係 半連線改寫
昨天聽了落落的課,講到了表與表之間的關係。以下是我的測試案例 select from departments d where d.department id in select e.department id from employees e 查詢表departments department id...
List集合之間的連線
之前學習資料庫的時候總結過資料庫中表和表之間的連線 資料庫中多表的連線 現在做的專案需要要呼叫其他系統wcf服務返回list集合,從自己系統再返回一部分集合,將這兩種集合鏈結起來再將 連線的集合 返回到介面。通過查閱資料,有兩種方法可以實現list集合之間的連線 一種是利用linq語句,另外一種是利...