Oracle優化之表連接方式

来源:https://www.cnblogs.com/blog-fan2018/archive/2019/04/12/10697002.html
-Advertisement-
Play Games

在Oracle資料庫中,兩個表之間的表連接方法有排序合併連接、嵌套迴圈連接、哈希連接和笛卡爾連接四種 1.排序合併連接(sort merge join) 排序合併連接是一種兩表在做表連接時用排序(SORT)操作和合併(MERGE)操作來得到連接結果集的表連接方法 如果t1表和t2表在做表連接時使用的 ...


在Oracle資料庫中,兩個表之間的表連接方法有排序合併連接、嵌套迴圈連接、哈希連接和笛卡爾連接四種

1.排序合併連接(sort merge join)

  排序合併連接是一種兩表在做表連接時用排序(SORT)操作和合併(MERGE)操作來得到連接結果集的表連接方法

  如果t1表和t2表在做表連接時使用的是排序合併連接,那麼Oracle會依次執行如下步驟:

    a.以目標SQL中指定的謂詞條件訪問t1表,然後對訪問結果按照t1表的連接列排序,排好序後的結果集記為s1

    b.以目標SQL中指定的謂詞條件訪問t2表,然後對訪問結果按照t2表的連接列排序,排好序後的結果集記為s2

    c.對s1和s2進行合併操作,從中取出匹配記錄作為最終的結果集

  排序合併連接的優缺點及適用場景:

    a.通常情況下hash join的效果都比sort merge join要好,但是,如果行源已經被排過序,在執行sort merge join時不需要再排序,這時sort merge join的性能會優於hash join

    b.通常情況下,只有在以下情況發生時,才會使用排序合併連接:

      1)RBO模式

      2)不等值連接(>,<,>=,<=)

      3)哈希連接被禁用時(_HASH_JOIN_ENABLED=false)

      4)數據源已排序

  --示例 

 1 SQL> select * from scott.emp t1,scott.emp t2 where t1.empno > t2.mgr;
 2 
 3 89 rows selected.
 4 
 5 
 6 Execution Plan
 7 ----------------------------------------------------------
 8 Plan hash value: 3950110903
 9 
10 ----------------------------------------------------------------------------------------
11 | Id  | Operation                     | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
12 ----------------------------------------------------------------------------------------
13 |   0 | SELECT STATEMENT              |        |    62 |  4712 |     6  (17)| 00:00:01 |
14 |   1 |  MERGE JOIN                   |        |    62 |  4712 |     6  (17)| 00:00:01 |
15 |   2 |   SORT JOIN                   |        |    14 |   532 |     2   (0)| 00:00:01 |
16 |   3 |    TABLE ACCESS BY INDEX ROWID| EMP    |    14 |   532 |     2   (0)| 00:00:01 |
17 |   4 |     INDEX FULL SCAN           | PK_EMP |    14 |       |     1   (0)| 00:00:01 |
18 |*  5 |   SORT JOIN                   |        |    14 |   532 |     4  (25)| 00:00:01 |
19 |   6 |    TABLE ACCESS FULL          | EMP    |    14 |   532 |     3   (0)| 00:00:01 |
20 ----------------------------------------------------------------------------------------
21 
22 Predicate Information (identified by operation id):
23 ---------------------------------------------------
24 
25    5 - access(INTERNAL_FUNCTION("T1"."EMPNO")>INTERNAL_FUNCTION("T2"."MGR"))
26        filter(INTERNAL_FUNCTION("T1"."EMPNO")>INTERNAL_FUNCTION("T2"."MGR"))
27 
28 
29 Statistics
30 ----------------------------------------------------------
31           1  recursive calls
32           0  db block gets
33           8  consistent gets
34           0  physical reads
35           0  redo size
36        6612  bytes sent via SQL*Net to client
37         575  bytes received via SQL*Net from client
38           7  SQL*Net roundtrips to/from client
39           2  sorts (memory)
40           0  sorts (disk)
41          89  rows processed
42 
43 SQL> 
View Code

2.嵌套迴圈連接(nested loops join)

  嵌套迴圈連接是一種兩表在做表連接時依靠兩層嵌套迴圈(外層迴圈/內層迴圈)來得到連接結果集的表連接方法

  如果t1表和t2表在做表連接時使用的是嵌套迴圈連接,那麼Oracle會依次執行如下步驟:

    a.首先,優化器會按照一定的規則來決定t1和t2誰是驅動表誰是被驅動表,驅動表用於外層迴圈,被驅動表用於記憶體迴圈。假設t1是驅動表

    b.以目標SQL中指定的謂詞條件訪問驅動表t1,得到結果集s1

    c.遍歷s1,同時遍歷被驅動表t2,即取出s1中的記錄按照連接條件和被驅動表t2做匹配。最終將得到的結果集返回

  嵌套迴圈連接的優缺點及適用場景:

    a.能夠實現快速響應,即可以第一時間先返回已經連接過且滿足連接條件的記錄,而不必等待所有的連接操作全部做完後才返回連接結果

    b.適用於驅動表所對應的驅動結果集的記錄數較少,同時在被驅動表的連接列上又存在唯一性索引(或者在被驅動表的連接列上存在選擇性很好的非唯一性索引)的情況

  --示例

SQL> select /*+ gather_plan_statistics use_nl(t1,t2)*/* from scott.emp t1,scott.dept t2 where t1.deptno = t2.deptno;
SQL> select * from table(dbms_xplan.display_cursor(null,0,'allstats,last'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  dcsf9m1rzzga5, child number 0
-------------------------------------
select /*+ gather_plan_statistics use_nl(t1,t2)*/* from scott.emp
t1,scott.dept t2 where t1.deptno = t2.deptno

Plan hash value: 4192419542

-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |      1 |        |     14 |00:00:00.01 |      32 |
|   1 |  NESTED LOOPS      |      |      1 |     14 |     14 |00:00:00.01 |      32 |
|   2 |   TABLE ACCESS FULL| DEPT |      1 |      4 |      4 |00:00:00.01 |       7 |
|*  3 |   TABLE ACCESS FULL| EMP  |      4 |      4 |     14 |00:00:00.01 |      25 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter("T1"."DEPTNO"="T2"."DEPTNO")


21 rows selected.

SQL> 
View Code

3.哈希連接(hash join)

  哈希連接是一種兩表在做表連接時依靠哈希運算來得到連接結果集的表連接方法,oracle 7.3之後引入

  Hash join的工作方式是將一個表(通常是小一點的那個表)做hash運算並存儲到hash列表中,從另一個表中抽取記錄,做hash運算,到hash 列表中找到相應的值,做匹配

 

  哈希連接只適用於CBO,也只能用於等值連接條件

  哈希連接很適合於小表和大表做連接,特別是在小表的連接列的可選擇性非常好的情況下,這時候哈希連接的執行時間就可以近似看作是和全表掃描那個大表所耗費的時間相當

  哈希連接時,驅動結果集對應的Hash Table能夠完全被容納在記憶體中(PGA的工作區),此時的哈希連接的執行效率非常高

  哈希連接的性能問題可以通過10104事件來診斷,相關說明如下:   

    Number of in-memory partitions (may have changed): Hash Partition
    Final number of hash buckets: Hash Bucket數量
    Total buckets: Empty buckets: Non-empty buckets: Hash Bucket中空記錄及非空記錄的情況
    Total number of rows: 驅動結果集的記錄數
    Maximum number of rows in a bucket: 包含記錄數最多的Hash Bucket所含記錄的數量
    Disabled bitmap filtering: 是否啟用點陣圖過濾

  --示例

 1 SQL> select /*+ gather_plan_statistics use_hash(t1,t2)*/* from scott.emp t1,scott.dept t2 where t1.deptno = t2.deptno;
 2 SQL> select * from table(dbms_xplan.display_cursor(null,0,'allstats,last'));
 3 
 4 PLAN_TABLE_OUTPUT
 5 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 6 SQL_ID  0j83q86ara5u2, child number 0
 7 -------------------------------------
 8 select /*+ gather_plan_statistics use_hash(t1,t2)*/* from scott.emp
 9 t1,scott.dept t2 where t1.deptno = t2.deptno
10 
11 Plan hash value: 615168685
12 
13 ----------------------------------------------------------------------------------------------------------------
14 | Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
15 ----------------------------------------------------------------------------------------------------------------
16 |   0 | SELECT STATEMENT   |      |      1 |        |     14 |00:00:00.01 |      13 |       |       |          |
17 |*  1 |  HASH JOIN         |      |      1 |     14 |     14 |00:00:00.01 |      13 |  1321K|  1321K| 1070K (0)|
18 |   2 |   TABLE ACCESS FULL| DEPT |      1 |      4 |      4 |00:00:00.01 |       6 |       |       |          |
19 |   3 |   TABLE ACCESS FULL| EMP  |      1 |     14 |     14 |00:00:00.01 |       7 |       |       |          |
20 ----------------------------------------------------------------------------------------------------------------
21 
22 Predicate Information (identified by operation id):
23 ---------------------------------------------------
24 
25    1 - access("T1"."DEPTNO"="T2"."DEPTNO")
26 
27 
28 21 rows selected.
29 
30 SQL> 
View Code
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Linux ssh登陸慢的兩種原因分析 如果做運維就一定會遇到ssh登陸Linux伺服器慢的問題,問題比較好解決,一般Google之後有很多文章都告訴你解決方法,但是很少有文章分析為什麼會慢,這篇文章簡單分析下ssh登陸慢的原因。 useDNS配置導致登陸慢 如果ssh server的配置文件(通常 ...
  • 1. 安裝基礎依賴 2. 下載源碼包 3.cd php-7.2.7 4.配置 5.make && make install 6.配置文件 # cp php.ini-development /usr/local/php/lib/php.ini # cp /usr/local/php/etc/php-f ...
  • 1. 安裝 2. 創建SSHFS 掛載目錄 3.使用SSHFS 掛載遠程的文件系統 sudo sshfs -o allow_other,IdentityFile=~/.ssh/id_rsa #username@site:/share1/home/siyuan /mnt/siyuan 例: sshfs ...
  • 想學習下JavaWeb,手頭有2017年有活動的時候買的一本書,還是全彩的,應該很適合我這種菜鳥技術渣。 只可惜照著書搭建了一套Web環境,代碼和db腳本都是拷貝的光碟里的,也反覆檢查了資料庫的連接情況,Navicat可以正常連,涉及到的兩個資料庫配置文件裡面的url、埠、密碼應該都是對的,反覆折 ...
  • 1.MongoDB數據歸檔的意義 和其他類型的資料庫一樣,歸檔對MongoDB同樣重要。通過歸檔,可以保持集合中合適的數據量,對資料庫的性能是一種保障,也就是大家常說的數據冷熱分離。 同時,歸檔對資料庫的管理也帶來了很大方便性,例如日常的備份、災難恢復等。 在此,不再展開敘述了。 2.集合數據歸檔流 ...
  • 使用Python3操作MySQL資料庫:創建表,插入數據,查詢數據,更新數據,刪除數據。 ...
  • Redis在3.0版本以後開始支持集群,經過中間幾個版本的不斷更新優化,最新的版本集群功能已經非常完善。本文簡單介紹一下Redis集群搭建的過程和配置方法,redis版本是5.0.4,操作系統是中標麒麟(和Centos內核基本一致)。 1、Redis集群原理 Redis 集群是一個提供在多個Redi ...
  • 首先資料庫的外鍵是資料庫提供的一種完整性約束。在許多資料庫的書上也會介紹到,然而對於外鍵這個完整性性約束究竟應該在資料庫端實現,還是在項目業務端實現很多人有著不同的意見。 在查看了很多大牛的文章後我總結出來如下: 個人開發(小型應用)、資料庫讀寫資源充足(資料庫併發低),集中式資料庫系統,則應該使用 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...