精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何優化MySQL中的join語句

jf_78858299 ? 來源:Java識堂 ? 作者:Java識堂 ? 2023-04-24 17:03 ? 次閱讀

在mysql中,join 主要有Nested Loop、Hash Join、Merge Join 這三種方式,我們今天來看一下最普遍 Nested Loop 循環連接方式,主要包括三種:

  • Simple Nested-Loop Join:簡單嵌套循環連接
  • Block Nested-Loop Join:緩存塊嵌套循環連接
  • Index Nested-Loop Join:索引嵌套循環連接

Simple Nested-Loop Join

我們來看一下當進行 join 操作時,mysql是如何工作的。常見的 join 方式有哪些?圖片如圖,當我們進行連接操作時,左邊的表是 「驅動表」 ,右邊的表是**「被驅動表」**

Simple Nested-Loop Join 這種連接操作是從驅動表中取出一條記錄然后逐條匹配被驅動表的記錄,如果條件匹配則將結果返回。然后接著取驅動表的下一條記錄進行匹配,直到驅動表的數據全都匹配完畢

「因為每次從驅動表取數據比較耗時,所以MySQL并沒有采用這種算法來進行連接操作」

Block Nested-Loop Join

圖片既然每次從驅動表取數據比較耗時,那我們每次從驅動表取一批數據放到內存中,然后對這一批數據進行匹配操作。這批數據匹配完畢,再從驅動表中取一批數據放到內存中,直到驅動表的數據全都匹配完畢

批量取數據能減少很多IO操作,因此執行效率比較高,這種連接操作也被MySQL采用

對了,這塊內存在MySQ中有一個專有的名詞,叫做 join buffer,我們可以執行如下語句查看 join buffer 的大小

show variables like '%join_buffer%'

圖片

把我們之前用的 single_table 表搬出來,基于 single_table 表創建2個表,每個表插入1w條隨機記錄

CREATE TABLE single_table (
    id INT NOT NULL AUTO_INCREMENT,
    key1 VARCHAR(100),
    key2 INT,
    key3 VARCHAR(100),
    key_part1 VARCHAR(100),
    key_part2 VARCHAR(100),
    key_part3 VARCHAR(100),
    common_field VARCHAR(100),
    PRIMARY KEY (id),
    KEY idx_key1 (key1),
    UNIQUE KEY idx_key2 (key2),
    KEY idx_key3 (key3),
    KEY idx_key_part(key_part1, key_part2, key_part3)
) Engine=InnoDB CHARSET=utf8;

create table t1 like single_table;
create table t2 like single_table;

如果直接使用 join 語句,MySQL優化器可能會選擇表 t1 或者 t2 作為驅動表,這樣會影響我們分析sql語句的過程,所以我們用 straight_join 讓mysql使用固定的連接方式執行查詢

select * from t1 straight_join t2 on (t1.common_field = t2.common_field)

運行時間為0.035s圖片執行計劃如下圖片在Extra列中看到了 Using join buffer ,說明連接操作是基于 「Block Nested-Loop Join」 算法

Index Nested-Loop Join

了解了 「Block Nested-Loop Join」 算法之后,可以看到驅動表的每條記錄會把被驅動表的所有記錄都匹配一遍,非常耗時,能不能提高一下被驅動表匹配的效率呢?

估計這種算法你也想到了,就是給被驅動表連接的列加上索引,這樣匹配的過程就非常快,如圖所示圖片我們來看一下基于索引列進行連接執行查詢有多快?

select * from t1 straight_join t2 on (t1.id = t2.id)

執行時間為0.001秒,可以看到比基于普通的列進行連接快了不止一個檔次圖片執行計劃如下圖片「驅動表的記錄并不是所有列都會被放到 join buffer,只有查詢列表中的列和過濾條件中的列才會被放入 join buffer,因此我們不要把 * 作為查詢列表,只需要把我們關心的列放到查詢列表就好了,這樣可以在 join buffer 中放置更多的記錄」

如何選擇驅動表?

知道了 join 的具體實現,我們來聊一個常見的問題,即如何選擇驅動表?

「如果是 Block Nested-Loop Join 算法:」

  1. 當 join buffer 足夠大時,誰做驅動表沒有影響
  2. 當 join buffer 不夠大時,應該選擇小表做驅動表(小表數據量少,放入 join buffer 的次數少,減少表的掃描次數)

「如果是 Index Nested-Loop Join 算法」

假設驅動表的行數是M,因此需要掃描驅動表M行

被驅動表的行數是N,每次在被驅動表查一行數據,要先搜索索引a,再搜索主鍵索引。每次搜索一顆樹近似復雜度是以2為底N的對數,所以在被驅動表上查一行的時間復雜度是

驅動表的每一行數據都要到被驅動表上搜索一次,整個執行過程近似復雜度為

「顯然M對掃描行數影響更大,因此應該讓小表做驅動表。當然這個結論的前提是可以使用被驅動表的索引」

「總而言之,我們讓小表做驅動表即可」

「當 join 語句執行的比較慢時,我們可以通過如下方法來進行優化」

  1. 進行連接操作時,能使用被驅動表的索引
  2. 小表做驅動表
  3. 增大 join buffer 的大小
  4. 不要用 * 作為查詢列表,只返回需要的列
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 驅動
    +關注

    關注

    12

    文章

    1826

    瀏覽量

    85179
  • MySQL
    +關注

    關注

    1

    文章

    802

    瀏覽量

    26445
  • Join
    +關注

    關注

    0

    文章

    9

    瀏覽量

    3247
收藏 人收藏

    評論

    相關推薦

    MySQL的執行過程 SQL語句性能優化常用策略

    回顧 MySQL 的執行過程,幫助介紹如何進行 sql 優化
    的頭像 發表于 12-12 10:26 ?625次閱讀
    <b class='flag-5'>MySQL</b>的執行過程 SQL<b class='flag-5'>語句</b>性能<b class='flag-5'>優化</b>常用策略

    【工具分享】labview與MYsql語句使用判斷

    語句執行1.寫入MYSQL語句2.執行語句3.語句執行成功創建表格1.寫入表格名與創建表格格式2.執行
    發表于 05-08 16:00

    begin ...... end 與 fork ...... join 語句的 區別 ------ 轉載

    ; end_wave; //語句5,觸發事件end_wave join并行塊的執行特點為: 并行語句塊內各條語句是各自獨立地同時開始執行的,各條語句
    發表于 06-02 21:31

    MaxCompute JOIN優化小結

    join各種場景優化都做了一些梳理,現實情況很可能是上述多場景的組合,這時候就需要靈活運用相應的優化方法,舉一反三。識別以下二維碼,閱讀更多干貨
    發表于 03-15 13:22

    mysql的7種JOIN

    mysqlJOIN大匯總
    發表于 03-11 11:18

    mysql基本語句詳細教程

    mysql基本語句詳細教程
    發表于 12-15 22:15 ?0次下載

    Join在Spark是如何組織運行的

    ,我們有必要了解Join在Spark是如何組織運行的。 SparkSQL總體流程介紹 在闡述Join實現之前,我們首先簡單介紹SparkSQL的總體流程,一般地,我們有兩種方式使用SparkSQL
    的頭像 發表于 09-25 11:35 ?2171次閱讀
    <b class='flag-5'>Join</b>在Spark<b class='flag-5'>中</b>是如何組織運行的

    SystemVerilog的fork-join

    在fork-join語句,每個語句都是并發進程。在這個語句,父進程一直被阻塞,直到所有由
    的頭像 發表于 12-09 11:58 ?2176次閱讀

    應用層關聯的優勢 MySQL不推薦使用join的原因

    對于mysql,不推薦使用子查詢和join是因為本身join的效率就是硬傷,一旦數據量很大效率就很難保證,強烈推薦分別根據索引單表取數據,然后在程序里面做join,merge數據。
    發表于 02-23 14:07 ?471次閱讀

    mysql增刪改查語句以及常用方法

    MySQL是一種熱門的關系型數據庫管理系統,廣泛用于各種Web應用程序和企業級應用程序。本文將詳細介紹MySQL的增刪改查語句以及常用方
    的頭像 發表于 11-16 15:36 ?1047次閱讀

    mysql數據庫的增刪改查sql語句

    SQL語句,以幫助讀者全面了解MySQL的基本操作。 一、增加數據 在MySQL數據庫,我們可以使用INSERT語句來向表
    的頭像 發表于 11-16 15:41 ?1151次閱讀

    mysql數據庫增刪改查基本語句

    MySQL是一種關系型數據庫管理系統,提供了豐富的功能和語法,來支持數據的增刪改查。在本文中,將詳細介紹MySQL數據庫的增、刪、改、查基本語句,以及一些常見用例。 一、數據的增加 在MySQ
    的頭像 發表于 11-16 16:36 ?919次閱讀

    mysql基礎語句大全

    MySQL的基礎語句可以分為以下幾類: 數據庫操作語句: 創建數據庫:CREATE DATABASE database_name; 刪除數據庫:DROP DATABASE database_name
    的頭像 發表于 11-16 16:42 ?1889次閱讀

    MySQL常用語句

    ,包括創建和管理數據庫、表、查詢和修改數據等方面。 一、數據庫的創建和管理 創建數據庫 MySQL創建數據庫的語句是CREATE DATABASE,語法如下: CREATE DATABASE
    的頭像 發表于 11-21 11:11 ?495次閱讀

    MySQL聯表查詢優化

    使用顯示連接left join(right join,inner join),盡量避免隱式連接(where逗號連接表 .... and .... and ...)這類寫法,假設三張表每張表有一千
    的頭像 發表于 04-24 12:33 ?546次閱讀
    <b class='flag-5'>MySQL</b>聯表查詢<b class='flag-5'>優化</b>