欧美性猛交xxxx免费看_牛牛在线视频国产免费_天堂草原电视剧在线观看免费_国产粉嫩高清在线观看_国产欧美日本亚洲精品一5区

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何優(yōu)化MySQL中的join語(yǔ)句

jf_78858299 ? 來(lái)源:Java識(shí)堂 ? 作者:Java識(shí)堂 ? 2023-04-24 17:03 ? 次閱讀

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

  • Simple Nested-Loop Join:簡(jiǎn)單嵌套循環(huán)連接
  • Block Nested-Loop Join:緩存塊嵌套循環(huán)連接
  • Index Nested-Loop Join:索引嵌套循環(huán)連接

Simple Nested-Loop Join

我們來(lái)看一下當(dāng)進(jìn)行 join 操作時(shí),mysql是如何工作的。常見(jiàn)的 join 方式有哪些?圖片如圖,當(dāng)我們進(jìn)行連接操作時(shí),左邊的表是 「驅(qū)動(dòng)表」 ,右邊的表是**「被驅(qū)動(dòng)表」**

Simple Nested-Loop Join 這種連接操作是從驅(qū)動(dòng)表中取出一條記錄然后逐條匹配被驅(qū)動(dòng)表的記錄,如果條件匹配則將結(jié)果返回。然后接著取驅(qū)動(dòng)表的下一條記錄進(jìn)行匹配,直到驅(qū)動(dòng)表的數(shù)據(jù)全都匹配完畢

「因?yàn)槊看螐尿?qū)動(dòng)表取數(shù)據(jù)比較耗時(shí),所以MySQL并沒(méi)有采用這種算法來(lái)進(jìn)行連接操作」

Block Nested-Loop Join

圖片既然每次從驅(qū)動(dòng)表取數(shù)據(jù)比較耗時(shí),那我們每次從驅(qū)動(dòng)表取一批數(shù)據(jù)放到內(nèi)存中,然后對(duì)這一批數(shù)據(jù)進(jìn)行匹配操作。這批數(shù)據(jù)匹配完畢,再?gòu)尿?qū)動(dòng)表中取一批數(shù)據(jù)放到內(nèi)存中,直到驅(qū)動(dòng)表的數(shù)據(jù)全都匹配完畢

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

對(duì)了,這塊內(nèi)存在MySQ中有一個(gè)專有的名詞,叫做 join buffer,我們可以執(zhí)行如下語(yǔ)句查看 join buffer 的大小

show variables like '%join_buffer%'

圖片

把我們之前用的 single_table 表搬出來(lái),基于 single_table 表創(chuàng)建2個(gè)表,每個(gè)表插入1w條隨機(jī)記錄

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 語(yǔ)句,MySQL優(yōu)化器可能會(huì)選擇表 t1 或者 t2 作為驅(qū)動(dòng)表,這樣會(huì)影響我們分析sql語(yǔ)句的過(guò)程,所以我們用 straight_join 讓mysql使用固定的連接方式執(zhí)行查詢

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

運(yùn)行時(shí)間為0.035s圖片執(zhí)行計(jì)劃如下圖片在Extra列中看到了 Using join buffer ,說(shuō)明連接操作是基于 「Block Nested-Loop Join」 算法

Index Nested-Loop Join

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

估計(jì)這種算法你也想到了,就是給被驅(qū)動(dòng)表連接的列加上索引,這樣匹配的過(guò)程就非???,如圖所示圖片我們來(lái)看一下基于索引列進(jìn)行連接執(zhí)行查詢有多快?

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

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

如何選擇驅(qū)動(dòng)表?

知道了 join 的具體實(shí)現(xiàn),我們來(lái)聊一個(gè)常見(jiàn)的問(wèn)題,即如何選擇驅(qū)動(dòng)表?

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

  1. 當(dāng) join buffer 足夠大時(shí),誰(shuí)做驅(qū)動(dòng)表沒(méi)有影響
  2. 當(dāng) join buffer 不夠大時(shí),應(yīng)該選擇小表做驅(qū)動(dòng)表(小表數(shù)據(jù)量少,放入 join buffer 的次數(shù)少,減少表的掃描次數(shù))

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

假設(shè)驅(qū)動(dòng)表的行數(shù)是M,因此需要掃描驅(qū)動(dòng)表M行

被驅(qū)動(dòng)表的行數(shù)是N,每次在被驅(qū)動(dòng)表查一行數(shù)據(jù),要先搜索索引a,再搜索主鍵索引。每次搜索一顆樹(shù)近似復(fù)雜度是以2為底N的對(duì)數(shù),所以在被驅(qū)動(dòng)表上查一行的時(shí)間復(fù)雜度是

驅(qū)動(dòng)表的每一行數(shù)據(jù)都要到被驅(qū)動(dòng)表上搜索一次,整個(gè)執(zhí)行過(guò)程近似復(fù)雜度為

「顯然M對(duì)掃描行數(shù)影響更大,因此應(yīng)該讓小表做驅(qū)動(dòng)表。當(dāng)然這個(gè)結(jié)論的前提是可以使用被驅(qū)動(dòng)表的索引」

「總而言之,我們讓小表做驅(qū)動(dòng)表即可」

「當(dāng) join 語(yǔ)句執(zhí)行的比較慢時(shí),我們可以通過(guò)如下方法來(lái)進(jìn)行優(yōu)化」

  1. 進(jìn)行連接操作時(shí),能使用被驅(qū)動(dòng)表的索引
  2. 小表做驅(qū)動(dòng)表
  3. 增大 join buffer 的大小
  4. 不要用 * 作為查詢列表,只返回需要的列
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 驅(qū)動(dòng)
    +關(guān)注

    關(guān)注

    12

    文章

    1853

    瀏覽量

    85691
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    831

    瀏覽量

    26763
  • Join
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    3271
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    MySQL的執(zhí)行過(guò)程 SQL語(yǔ)句性能優(yōu)化常用策略

    回顧 MySQL 的執(zhí)行過(guò)程,幫助介紹如何進(jìn)行 sql 優(yōu)化
    的頭像 發(fā)表于 12-12 10:26 ?719次閱讀
    <b class='flag-5'>MySQL</b>的執(zhí)行過(guò)程 SQL<b class='flag-5'>語(yǔ)句</b>性能<b class='flag-5'>優(yōu)化</b>常用策略

    【工具分享】labview與MYsql語(yǔ)句使用判斷

    語(yǔ)句執(zhí)行1.寫(xiě)入MYSQL語(yǔ)句2.執(zhí)行語(yǔ)句3.語(yǔ)句執(zhí)行成功創(chuàng)建表格1.寫(xiě)入表格名與創(chuàng)建表格格式2.執(zhí)行語(yǔ)
    發(fā)表于 05-08 16:00

    begin ...... end 與 fork ...... join 語(yǔ)句的 區(qū)別 ------ 轉(zhuǎn)載

    ; end_wave; //語(yǔ)句5,觸發(fā)事件end_wave join并行塊的執(zhí)行特點(diǎn)為: 并行語(yǔ)句塊內(nèi)各條語(yǔ)句是各自獨(dú)立地同時(shí)開(kāi)始執(zhí)行的,各條語(yǔ)句
    發(fā)表于 06-02 21:31

    MaxCompute JOIN優(yōu)化小結(jié)

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

    mysql的7種JOIN

    mysqlJOIN大匯總
    發(fā)表于 03-11 11:18

    mysql基本語(yǔ)句詳細(xì)教程

    mysql基本語(yǔ)句詳細(xì)教程
    發(fā)表于 12-15 22:15 ?0次下載

    Join在Spark是如何組織運(yùn)行的

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

    SystemVerilog的fork-join

    在fork-join語(yǔ)句,每個(gè)語(yǔ)句都是并發(fā)進(jìn)程。在這個(gè)語(yǔ)句,父進(jìn)程一直被阻塞,直到所有由
    的頭像 發(fā)表于 12-09 11:58 ?2314次閱讀

    應(yīng)用層關(guān)聯(lián)的優(yōu)勢(shì) MySQL不推薦使用join的原因

    對(duì)于mysql,不推薦使用子查詢和join是因?yàn)楸旧?b class='flag-5'>join的效率就是硬傷,一旦數(shù)據(jù)量很大效率就很難保證,強(qiáng)烈推薦分別根據(jù)索引單表取數(shù)據(jù),然后在程序里面做join,merge數(shù)據(jù)。
    發(fā)表于 02-23 14:07 ?511次閱讀

    mysql增刪改查語(yǔ)句以及常用方法

    MySQL是一種熱門的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),廣泛用于各種Web應(yīng)用程序和企業(yè)級(jí)應(yīng)用程序。本文將詳細(xì)介紹MySQL的增刪改查語(yǔ)句以及常用方
    的頭像 發(fā)表于 11-16 15:36 ?1201次閱讀

    mysql數(shù)據(jù)庫(kù)的增刪改查sql語(yǔ)句

    SQL語(yǔ)句,以幫助讀者全面了解MySQL的基本操作。 一、增加數(shù)據(jù) 在MySQL數(shù)據(jù)庫(kù),我們可以使用INSERT語(yǔ)句來(lái)向表
    的頭像 發(fā)表于 11-16 15:41 ?1338次閱讀

    mysql數(shù)據(jù)庫(kù)增刪改查基本語(yǔ)句

    MySQL是一種關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),提供了豐富的功能和語(yǔ)法,來(lái)支持?jǐn)?shù)據(jù)的增刪改查。在本文中,將詳細(xì)介紹MySQL數(shù)據(jù)庫(kù)的增、刪、改、查基本語(yǔ)句,以及一些常見(jiàn)用例。 一、數(shù)據(jù)的增加 在MySQ
    的頭像 發(fā)表于 11-16 16:36 ?1032次閱讀

    mysql基礎(chǔ)語(yǔ)句大全

    。 MySQL的基礎(chǔ)語(yǔ)句可以分為以下幾類: 數(shù)據(jù)庫(kù)操作語(yǔ)句: 創(chuàng)建數(shù)據(jù)庫(kù):CREATE DATABASE database_name; 刪除數(shù)據(jù)庫(kù):DROP DATABASE database_name
    的頭像 發(fā)表于 11-16 16:42 ?2046次閱讀

    MySQL常用語(yǔ)句

    ,包括創(chuàng)建和管理數(shù)據(jù)庫(kù)、表、查詢和修改數(shù)據(jù)等方面。 一、數(shù)據(jù)庫(kù)的創(chuàng)建和管理 創(chuàng)建數(shù)據(jù)庫(kù) MySQL創(chuàng)建數(shù)據(jù)庫(kù)的語(yǔ)句是CREATE DATABASE,語(yǔ)法如下: CREATE DATABASE
    的頭像 發(fā)表于 11-21 11:11 ?573次閱讀

    MySQL聯(lián)表查詢優(yōu)化

    使用顯示連接left join(right join,inner join),盡量避免隱式連接(where逗號(hào)連接表 .... and .... and ...)這類寫(xiě)法,假設(shè)三張表每張表有一千
    的頭像 發(fā)表于 04-24 12:33 ?654次閱讀
    <b class='flag-5'>MySQL</b>聯(lián)表查詢<b class='flag-5'>優(yōu)化</b>