MySQL的驅動表與被驅動表

来源:https://www.cnblogs.com/EricZhao-/archive/2023/10/13/17761481.html
-Advertisement-
Play Games

驅動表與被驅動表的含義 在MySQL中進行多表聯合查詢時,MySQL會通過驅動表的結果集作為基礎數據,在被驅動表中匹配對應的數據,匹配成功合併後的臨時表再作為驅動表或被驅動表繼續與第三張表進行匹配合併,直到所有表都已匹配完畢,最後將結果返回出來。匹配演算法:Nested-Loop Join(嵌套迴圈連 ...


驅動表與被驅動表的含義

在MySQL中進行多表聯合查詢時,MySQL會通過驅動表的結果集作為基礎數據,在被驅動表中匹配對應的數據,匹配成功合併後的臨時表再作為驅動表或被驅動表繼續與第三張表進行匹配合併,直到所有表都已匹配完畢,最後將結果返回出來。匹配演算法:Nested-Loop Join(嵌套迴圈連接),在MySQL中有三種具體的實現演算法:

  • Simple Nested-Loop Join:簡單嵌套迴圈連接
  • Index Nested-Loop Join:索引嵌套迴圈鏈接
  • Block Nested-Loop Join:緩存快嵌套迴圈鏈接

Simple Nested-Loop Join

簡單嵌套迴圈連接實際上就是簡單粗暴的嵌套迴圈,如果驅動表有100條數據,被驅動表有100條數據,那麼在匹配時會將驅動表的每一條數據作為匹配條件去被驅動表中逐個比較,實際上就要比較100*100=10000次,可以想象這種比較效率是非常低下的。

Index Nested-Loop Join

索引嵌套迴圈連接是基於被驅動表的索引進行連接的演算法,通過驅動表的匹配條件與被驅動表的索引進行匹配,避免和每條記錄比較,從而利用索引的查詢減少匹配次數,提高查詢的性能。但要註意的是被驅動表的關聯條件必須要有索引時才能用到Index Nested-Loop Join。另外由於用到索引,如果是非聚簇索引並且查詢的數據包含了被驅動表的其他欄位,則會回到被驅動表再查詢一次對應的數據,即回表,多了IO操作。

Block Nested-Loop Join

緩存嵌套迴圈連接通過一次性緩存多條驅動表數據、參與查詢的列到Join Buffer里,然後拿Join Buffer里的數據批量與被驅動表中的數據進行比較,從而減少了迴圈匹配次數。

關於Join Buffer

  1. Join Buffer會緩存所有參與查詢的列,而不是只有Join的匹配列
  2. 可以調整MySQL的join_buffer_size緩存大小,join_buffer_size的預設值是256K,最大值在MySQL 5.1.22版本前是4G,而之後的版本才能在64位操作系統下申請大於4G的空間
  3. 要使用Block Nested-Loop Join演算法需要開啟優化器管理配置的optimizer_switch的設置block_nested_loop為on,預設為on

當查詢優化器不使用Index Nested-Loop Join演算法的時候,預設使用Block Nested-Loop Join演算法。

聯合查詢的性能優化原則

明白聯合查詢的原理是驅動表與被驅動表通過條件嵌套迴圈連接匹配後,查詢性能優化的思路就是:減少迴圈比較次數。可以通過以下幾個原則來進行優化。

1. 以數據量小的表作為驅動表,數據量大的表作為被驅動表。

通過上面的分析可以得知,MySQL在聯合查詢中是用驅動表的數據作為篩選條件在被驅動表中進行匹配,所以假設table1作為驅動表,數據有10000條,table2作為被驅動表的數據有100條,並且被table2中有索引,那麼用Index Nested-Loop Join演算法進行匹配時要進行10000次的關聯操作。但如果反過來用table2作為驅動表,table1作為被驅動表,只需要進行100次關聯即可完成匹配,效率也會大大提高,其他的連接演算法也類似。簡單說通常情況下要用小表驅動大表。
但是這裡的小表和大表是根據查詢條件相對而言的,大小的計算是要根據查詢條件和具體的欄位進行衡量,假如查詢條件指定了table1的搜索範圍,即table1滿足查詢條件的行數有90行,那麼計算公式為:90乘以參與關聯查詢欄位的大小總和,若結果小於table2滿足查詢條件後的行數乘以參與關聯查詢欄位的大小,則table1為小表,否則table1為大表。

2. 為匹配的條件增加索引

匹配的條件欄位列儘量使用有索引的,爭取使用Index Nested-Loop Join演算法進行關聯,減少被驅動表的迴圈次數

3. 增大join_buffer_size的大小

當使用Block Nested-Loop Join演算法時,增大join_buffer_size的大小可以使驅動表一次緩存更多的數據,從而減少總體迴圈匹配的次數

4. 減少不必要的欄位查詢

  • 當用到Block Nested-Loop Join演算法時,欄位越少,join Buffer所緩存的數據就越多,那麼迴圈的次數就越少。
  • 當用到Index Nested-Loop Join演算法時,如果可以不回表查詢,即只查詢索引列,利用覆蓋索引則可能提升匹配效率

如何確定驅動表與被驅動表

  • 在使用join連接並且無where條件時:
    1. left join左邊的表為驅動表,右邊的為被驅動表
    2. right join右邊的表為驅動表,左邊的為被驅動表
    3. 使用join時,MySQL會自動判斷左右兩邊哪邊是小表,哪邊是大表。小表作為驅動表,大表作為被驅動表,小表與大表的判斷原則為上面講到的根據行數和參與關聯的欄位計算得出。
  • 在使用in\exists時
    1. 使用in時,驅動表和被驅動表由MySQL的執行器根據表的大小自動選擇
    2. 使用exists時,外部表為驅動表,內部表為被驅動表。無論加什麼查詢條件都無法改變

使用join連接查詢時如果有where條件,則MySQL執行器會根據查詢條件過濾後的結果自動選擇驅動表或被驅動表。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目錄一、微處理器與匯流排1.微處理器的概述1.1 運算器1.2 控制器1.2.1 指令控制1.2.2 時序控制1.2.3 操作控制二、8086/8088微處理器1.8086/8088CPU的指令特點1.1 指令流水線1.2 記憶體的分段管理技術1.3 支持多處理器系統2.8088/8086的外部引腳及其 ...
  • 本腳本通過域管下發預設為root許可權執行 #!/bin/bash cd /home #快捷方式圖標名稱 string_imgName="temp1.png" #快捷方式文件名稱 string_fileName="/changePassword.desktop" #快捷方式內容 function in ...
  • Tcpdump 抓包工具使用以及Wireshark解析pacp包 參考鏈接(比較詳細):https://blog.csdn.net/weixin_42866036/article/details/128004750 1.項目上數據在共用時,由於介面有Token鑒權動作,有時調用介面會出現鑒權失效問題 ...
  • 前言 存儲引擎都是把數據存儲在文件系統上,通過通過查詢命令,可以查看數據目錄所在的本機路徑。 mysql> SHOW VARIABLES LIKE 'datadir'; + + + | Variable_name | Value | + + + | datadir | /var/lib/mysql/ ...
  • Trino是一款開源的高性能、分散式SQL查詢引擎,專門用於對各種異構數據源運行互動式分析查詢,支持從GB到PB的數據量範圍。 ...
  • 解決SUM函數返回為NULL SUM函數的作用:計算某一欄位中所有行的數值和, 使用SUM函數進行對符合條件的結果行數進行求和。 問題產生: sum 求和時會對 null 進行過濾,不計算,但如果沒有返回結果,則sum 函數的返回值為 null,不是 0: 解決方式: 1. IFNULL 使用IFN ...
  • 在DBS-集群列表-更多-連接查詢-死鎖中,看到9月22日有資料庫死鎖日誌,後排查發現是因為mysql的優化-index merge(索引合併)導致資料庫死鎖。 ...
  • 本文分享自華為雲社區《【SQL優化】為什麼有時候無法走執行性能更優的hashjoin》,作者: leapdb。 1. hash join通常優於nestloop join 通常nestloop join的複雜度是O(N方),hash join時間複雜度是O(N),所以我們一般傾向於使用hash jo ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...