以乙個比較兩本字典來做例子:
一本字典有索引目錄(dict a), 一本沒有(dict b)
現在要找出所有a開頭的單詞的異同
那麼比較的時候,你會怎麼比較?
合理的做法應該是以沒有索引的字典dict b開始, 找到a開頭的那一頁, 然後對於每個單詞, 通過使用索引在dict a中找到相應的條目
如果反過來, 效率會相同嗎?
驅動表,通俗的講就是先從哪個表開始檢索,良好的驅動表是成功優化的一半
例如:select * from a,b where a.id = b.id and a.姓名 = '美格瑞恩' and b.性別 = '女';
在a,b表同等數量級的情況下,顯然用a表做為驅動表比較好
因為姓名相對於性別來說可以過濾掉更多的資料
所以想辦法使你的執行計畫先掃瞄a表再通過nest loop與b表關連比較理想
一般而言,2個表的時候,選擇小表;3個或者以上的時候,選擇關聯比較多的表作為驅動表
不過,事無絕對,看個案例先:
有兩個表t1和t2,可以假設t1存放姓名、id這些基本資訊,每行較短
而t2也有id列和一些說明、備註類資訊,每行長的可能有一兩千個位元組
對於這兩個表,使用巢狀迴圈連線,t1表佔的塊數比較少,是小表
而t2表佔的塊數幾倍於t1,是大表。那麼,應該t1做驅動表更好一些,但實際卻是t2大表做驅動表更好
乙個不知道dba還是開發,不知道這一點,為了強制小表t1做驅動表,寫了類如下語句:
select /*+ ordered use_nl(t1,t2) */ from t2,t1 where t1.id=t2.id;
後來這個語句造成了一些效能問題。通過了解巢狀迴圈的工作方式,發現這裡的確是大表做驅動表好一些
這裡就說明了乙個問題,都說巢狀迴圈要小表做驅動表,如果不知道這是為什麼,這很容易造**雲亦雲
這樣只知其表,而不知其裡,很容易影響以後在某些問題上做出的判斷
驅動表(driving table/outer table)又稱為外層表,驅動表僅僅用於nested_loop join 和 hash join
驅動表是用來驅動查詢的
在cbo中,優化器會根據cost自動選擇驅動表,與表的順序無關
通常情況下,驅動表的選擇性較高(該列唯一鍵與列的比值較高),where中的限制條件較多,返回的行數較少的表適合做驅動表
事實上,大表有時候也會做驅動表,只要在大表上面限制條件較多,從大表上面返回的行數較少的話,大表也適合做驅動表
始終要記住的就是返回的結果集(某個表被過濾後的資料,或者某些表join 產生的資料)較小的表適合做驅動表
也就是說,哪個返回資料少 ,哪個就做驅動表,即連線操作應從返回較少行上驅動
我們在看執行計畫的時候,離nested loops,hash join 近的表就是驅動表,也就是說執行計畫中靠上的表是驅動表
以下是幾個快速判斷驅動表的經驗,可能有錯哦:
(1)用於連線的子句的列應被索引、在where子句中應盡量利用索引,而不是避開索引
(2)連線操作應從返回較少行上驅動
(3)如果所連線的表a和b,a表長度遠遠大於b表,建議從較大的a表上驅動
(4)如果where子句中含有選擇性條件,where no=20,將最具有選擇性部分放在表示式最後
(5)如果只有乙個表有索引,另一表無索引,無索引的表通常作為驅動表。如a表的no列以被索引
而b表的no列沒被索引,則應當b表作為驅動表,a表作為被驅動表
rule 下所謂驅動表
我們以 nested loop 為例:
如果兩個表連線欄位都沒有索引(通常這個時候是 sort merge / hash join),則驅動表會選擇後者
若兩個表其中有乙個有索引而另外乙個沒有索引,則驅動表是沒有索引那乙個,跟順序無關
若兩個表都有索引,則驅動表為 後面 那乙個表
所以事實上,rule下,只有在兩個表都存在連線欄位的索引的情況下才需要考慮順序問題
也就是小表放在後面大表放在前面(當然到底哪個好這實際上還跟符合條件的記錄數、資料分布等因素相關!,所以應該以實際測試為準)
而如果是 cbo 下,則跟順序無關
關鍵的是明白執行計畫,而不在於記住什麼規則
例如,表連線返回一條記錄
存在2張表,乙個10條記錄,乙個1000萬條記錄
若2表都存在連線字段索引,
以小表為驅動表,則代價為:
10*(通過索引在大表查詢一條記錄的代價)
以大表為驅動表,則代價為:
1000萬*(通過索引在小表查詢一條記錄的代價)
通過索引獲取一條記錄,10rows的表,代價通常在3 blocks,索引2塊,表1塊
而如果是1000萬的表,索引可能達到4塊,表1塊,速度·掰著腳趾頭都知道了哈
深入理解Oracle表 2 驅動表的那些事兒
以乙個比較兩本字典來做例子 一本字典有索引目錄 dict a 一本沒有 dict b 現在要找出所有a開頭的單詞的異同 那麼比較的時候,你會怎麼比較?合理的做法應該是以沒有索引的字典dict b開始,找到a開頭的那一頁,然後對於每個單詞,通過使用索引在dict a中找到相應的條目 如果反過來,效率會...
C 深入理解虛表
虛表是記錄本類中所有虛函式位址的乙個 如下,我們設計了乙個類,存在兩個虛函式。class a virtual void fun2 通過a例項化a,再看看a的記憶體結構。vfptr就是虛表!可以把它看成存放了void 型物件的陣列。而 vfptr的兩個成員分別代表fun1函式的指標和fun2函式的指標...
深入理解SQL表連線(join)
關聯式資料庫中最重要的兩個概念,當屬表連線和聚合。表連線將一條資料分開成多條,表聚合將多條合成一條。這一分一合,形成了關聯式資料庫強大的邏輯表達能力,這篇文章講表連線,關於聚合請移步 深入理解sql分組聚合 內連線 外連線 左外連線 右外連線 全連線 交叉連線 自然連線 這麼多種連線方式,你是不是已...