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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...