<li id="kueim"></li>
<abbr id="kueim"><tr id="kueim"></tr></abbr>
  • <ul id="kueim"></ul>
    <ul id="kueim"></ul>
    
    
    <strike id="kueim"><rt id="kueim"></rt></strike>
  • 長沙快付新聞資訊
    您當前的位置是: 首頁->技術資訊->mssql數據庫問題

    Oracle表聯結方法及原理介紹

    首發: 長沙快付 版權所有,未經許可嚴禁轉載
       如果查詢涉及多張表,在優化器確定了每個表最恰當的訪問方法后,下一步就是確定將這些表聯結起來的最佳方法以及最恰當的順序。表之間的關系通過WHERE子句中的條件來定義,若未定義則會產生笛卡爾積。
      
      聯結的方法有:嵌套循環聯結、排序-合并聯結、散列聯結及笛卡爾聯結。
      
      每個聯結方法都會選擇一對表,所訪問的第一張表通常被稱為驅動表(the driving table),訪問的第二張表則被稱為內層表或被驅表(inner或driven-to table)。
      
      優化器會根據WHERE子句篩選后得到的表行數進行估算,大小(塊、數據行及字節)最小的表通常被作為驅動表。
      
      通俗來講,就是“小表驅動大表”。在FROM子句中,最小的表放在最后,作為驅動表來使用。“小表驅動大表”在兩表都沒有索引時常見,可能你跟我一樣認為小驅大或大驅小沒有差別。這里長沙做網站為了方便理解舉個例子,但不一定正確,如:T1表有10行,T2表有10000行,1個塊可以放10行數據。那么,以T1為驅動,則T1掃描1個塊,內層T2掃描10次,共掃描塊為(1+1000*10=10001);以T2為驅動,則T2掃描1000個塊,內層T1掃描10000次,共掃描塊為(1000+1*10000=11000)。所以,你看到了,小表驅動大表掃描塊數更少。也就是說,表聯結時循環塊是固定的,主要差別在于掃描驅動表的塊數。
      
      有兩種情況可能驅動表并非最小的表:
      
      當優化器可以確定聯結的列在其中一張表基于UNIQUE或PRIMARY KEY約束時,即存在索引時,沒有索引的表將被作為驅動表。
      
      當使用外聯結時,外聯結的表必須放在所聯結表的后面。
      
      嵌套循環聯結
      
      如果結果集大小有限并且聯結條件列在其中一表上是索引時采用這種方法最高效。嵌套循環聯結的運算成本主要是讀取外層表(驅動表)中的每一行并將其與所匹配的內層表中的行聯結所需要的成本(這個不好理解,還是理解我上面舉的例子吧)。
      
      當數據行經過外層條件篩選并被確認匹配后,這些行就會逐個進入到內層循環。然后基于聯結列進行逐行檢查是否與被聯結表中的某一行相匹配,如果匹配就會被傳遞到查詢計劃的下一步或者如果沒有更多步驟直接被包含在最終結果集中。
      
      這種聯結的強大之處在于使用的內存非常少,因為數據集一次只加工一行,所需要的開支也非常小。
      
      在執行計劃中NESTED LOOPS表明使用了嵌套循環聯結。
      
      下面舉例說明當聯結列在基本一表是索引時另一表作為驅動表的情形:
      
      select empno,ename,dname,loc
      
      from emp,dept
      
      where emp.deptno = dept.deptno;
      
      在本例中,盡管dept在FROM子句的最后,優化器也會選擇emp將作為驅動表(外層表),dept作為被驅表(內層表)。首先對emp表進行全表掃描,所有塊通過多塊讀方式讀出,再逐行訪問,并將聯結列(deptno)傳遞給內層循環針對dept表的查詢。對于內聯結,每一行在dept表的deptno列有匹配值的數據行都將被返回。對于外聯結,emp表的每一行都將被返回,dept表中無法匹配的列將用NULL值來填充。
      
      優化器之所以不選擇dept表(即小又在FROM子句最后)作為驅動表,原因如下:
      
      emp表在deptno列上沒有索引,訪問它的唯一方法就是全表掃描。如果將dept表選為驅動表,對于dept表中的每一行都要在emp表中進行全表掃描。但若使用emp表作為驅動表,只需要對emp進行一次全表掃描,對于dept表則采用deptno上的索引進行索引掃描。針對索引而言,deptno又正好是主鍵列,所以采用INDEX UNIQUE SCAN速度極快。
      
      當然,我們也可以通過hint提示強制優化器使用某張表為驅動表,語法如下:
      
      select /*+ ordered use_nl(dept emp) */ empno,ename,dname,loc
      
      from emp,dept
      
      where emp.deptno = dept.deptno;
      
      排序-合并聯結
      
      排序-合并聯結獨立地讀取需要聯結的兩張表,分別對表中數據行按聯結列進行排序,然后對排序后的行集進行合并。當然,在數據行排序前會經過WHERE子句篩選。
      
      使用這種聯結方式對排序的開銷非常大,尤其是內存不足而使用臨時磁盤空間時。但一旦數據行排序完成,合并的過程是非常快的。
      
      在合并時,數據庫輪流操作兩個列表,比較最上面的數據行,丟棄在排序隊列中比另一個列表中的最上面的行出現得早的數據行,并只返回匹配的行。
      
      在執行計劃中,MERGE JOIN表明使用了排序-合并聯結。
      
      在對兩個表進行排序時,其實又加到了之前講過的數據訪問方式的選擇。一般而言,在聯結列在某表中正好是索引時,則可通過INDEX FULL SCAN來掃描,這樣將避免排序操作。沒有索引的表則只能通過全表掃描,然后進行排序了。
      
      這種聯結方式適用于:
      
      數據篩選條件有限并返回有限數據行的查詢;
      
      沒有可用的更直接訪問數據的索引;
      
      在條件為非等式的時候,如謂語有between等;
      
      如果數據行源非常大,這種聯結方式可能是唯一可行的選擇;
      
      同樣,我們可以通過hint提示強制使用這種聯結方式,如:
      
      select /*+ ordered */ empno,ename,dname,loc
      
      from emp,dept
      
      where emp.deptno = dept.deptno;
      
      散列聯結
      
      前面講過,排序-合并聯結用來處理特定的非等式條件,而散列聯結則只有在等值聯結時才能進行。散列聯結與排序-合并聯結類似,建立散列表所需要的數據塊被讀取,然后剩下的工作將會針對放在內存或臨時磁盤空間的散列數據來進行。散列聯結具體工作方式如下:
      
      首先,兩表都經過WHERE子句篩選得到行數據。然后基于表和索引的統計信息,被確定為返回最少行數的表被完全散列化(對聯結列運用hash函數)到內存中。這個散列表包含了原表的所有數據行并被基于聯結鍵的散列值(hash值)的隨機函數載入到“散列桶”中。只要有足夠的內存空間,這個散列表將一直放在內存中。如果沒有足夠的內存,散列表將會被寫入臨時磁盤空間。
      
      其次,讀取另一張較大的表并對聯結鍵應用散列函數,然后利用得到的散列值跟內存中散列表進行匹配以尋找存放有相應行數據的“散列桶”。如果匹配成功,則返回這一行數據,否則丟棄。較大的表只讀取一次,并檢查其中的每一行來匹配。這與嵌套循環聯結不同之處在于此處內層表被多次讀取(內層表被多次讀取的不應該是NESTED LOOP嗎,而HASH JOIN好像才是內層表只被讀一次吧)。
      
      在執行計劃中,散列聯結用HASH JOIN來表示。
      
      在散列聯結的執行計劃中,較小的散列表列在前面而探測表列在后面。決定哪個表最小的不僅取決于數據行數還取決于這些行的大小,因為整個行都必須要存放在散列表中。
      
      當數據行源較大并且結果集也較大的情況下將更傾向于考慮散列聯結,或者如果要聯結的其中一張表確定總是返回同一數據行源,也可能會選用散列聯結因為這樣僅訪問一次這張表。如果在這種情況下選用嵌套循環聯結,這個數據行源就會被一遍一遍地訪問,需要比單獨訪問一次多做很多工作。最后,如果較小的表可以放到內存中,散列聯結也會很受歡迎。
      
      笛卡爾聯結
      
      笛卡爾聯結發生在當一張表中的所有行與另一張表中的所有行聯結的時候。
      
      在執行計算中,MERGE JOIN CARTESIAN表明使用笛卡爾聯結。
      
      笛卡爾聯結可能會導致得到很多重復行的結果集,此時若使用distinct雖然可以去除重復行,但代價極高,需要先排序再卻重。所以我們最好避免產生笛卡爾積。
      
      外聯結
      
      外聯結需要外聯結表作為驅動表,這意味著有可能不能選用更加優化的聯結執行順序。因此,使用外聯結要格外小心,因為它的選用有可能會影響到整個執行計劃的性能。
    • 最新簽約客戶
    • 最新上線網站
    為什么選擇長沙快付公司?

    8年專業做網站經驗
    幫助您解決各種需求,并得到滿意方案

    效果滿意后付款
    預付30%定金,效果讓您滿意后,付全款

    資深用戶體驗設計師
    秉承"一切以用戶價值為依歸"理念,重視用戶體驗,專為企業需求進行定制

    采用國際標準結構建站
    DIV+CSS國際標準構建網頁,可有效提高網站訪問速度、提高網站頁面的可維護

    實現網絡營銷[SEO]最大化
    網站程序中融入SEO,有效降低企業成本

    分享到:
    主站蜘蛛池模板: 精品不卡一区二区| 国产精品视频a播放| 国产成人精品免费视| 亚洲精品国产品国语在线| 国产亚洲精品精品国产亚洲综合| 精品国产日产一区二区三区| 久久精品亚洲日本波多野结衣| 日韩一区二区精品观看| 国产一区精品| 亚洲自偷自偷精品| 精品一区二区三区中文字幕| 国产精品亲子乱子伦xxxx裸| 日韩av无码久久精品免费| 亚洲AV无码之日韩精品| 精品精品国产国产| 国产香蕉国产精品偷在线| 亚洲国产精品免费视频| 欧美高清在线精品一区| 久久国产精品-久久精品| 第一福利永久视频精品| 成人精品视频在线观看| 98视频精品全部国产| 国产精品亚洲一区二区三区在线| 日韩精品人妻系列无码专区免费| 亚洲线精品一区二区三区| 亚洲性日韩精品国产一区二区| 亚洲国产小视频精品久久久三级 | 亚洲AV无码久久精品蜜桃| 无码欧精品亚洲日韩一区夜夜嗨| 欧美国产精品久久高清| 日韩视频中文字幕精品偷拍| 亚洲国产精品成人网址天堂| 亚洲精品一品区二品区三品区| 亚洲国产精品18久久久久久| 久久亚洲中文字幕精品有坂深雪| 久久国产精品一国产精品金尊 | 欧美精品亚洲精品日韩| 亚洲精品免费视频| 国产精品亚洲二区在线观看| 精品人妻伦一二三区久久| 日韩精品亚洲专区在线观看|