gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

簡單聊聊MySQL中join查詢

本篇文章給大家?guī)砹岁P(guān)于mysql的相關(guān)知識,其中主要介紹了關(guān)于join查詢的相關(guān)問題,下面一起來看一下,希望對大家有幫助。

簡單聊聊MySQL中join查詢

程序員必備接口測試調(diào)試工具:立即使用
Apipost = Postman + Swagger + Mock + Jmeter
Api設(shè)計(jì)、調(diào)試、文檔、自動化測試工具
后端、前端、測試,同時(shí)在線協(xié)作,內(nèi)容實(shí)時(shí)同步

推薦學(xué)習(xí):mysql視頻教程

索引對 join 查詢的影響

數(shù)據(jù)準(zhǔn)備

假設(shè)有兩張表 t1、t2,兩張表都存在有主鍵索引 id 和索引字段 a,b 字段無索引,然后在 t1 表中插入 100 行數(shù)據(jù),t2 表中插入 1000 行數(shù)據(jù)進(jìn)行實(shí)驗(yàn)

CREATE TABLE `t2` (  `id` int NOT NULL,  `a` int DEFAULT NULL,  `b` int DEFAULT NULL,  PRIMARY KEY (`id`),  KEY `t2_a_index` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;  CREATE PROCEDURE **idata**() BEGIN   DECLARE i INT;   SET i = 1;   WHILE (i <= 1000)do     INSERT INTO t2 VALUES (i,i,i);     SET i = i +1;     END WHILE; END; CALL **idata**(); CREATE TABLE t1 LIKE t2; INSERT INTO t1 (SELECT * FROM t2 WHERE id <= 100);
登錄后復(fù)制

有索引查詢過程

我們使用查詢 SELECT * FROM t1 STRAIGHT_JOIN t2 ON (t1.a=t2.a);因?yàn)?join 查詢 MYSQL 優(yōu)化器不一定能按照我們的意愿去執(zhí)行,所以為了分析我們選擇用 STRAIGHT_JOIN 來代替,從而更直觀的進(jìn)行觀察

簡單聊聊MySQL中join查詢 圖 1

可以看出我們使用了 t1 作為驅(qū)動表,t2 作為被驅(qū)動表,上圖的 explain 中顯示本次查詢用上了 t2 表的字段 a索引,所以這個(gè)語句的執(zhí)行過程應(yīng)該是下面這樣的:

  • 從 t1 表中讀取一行數(shù)據(jù) r

  • 從數(shù)據(jù) r中取出字段 a到表 t2 中進(jìn)行匹配

  • 取出 t2 表中符合條件的行,和 r組成一行作為結(jié)果集的一部分

  • 重復(fù)執(zhí)行步驟 1-3,直到表 t1 循環(huán)數(shù)據(jù)

該過程稱之為 Index Nested-Loop Join,在這個(gè)流程里,驅(qū)動表 t1 進(jìn)行了全表掃描,因?yàn)槲覀兘o t1 表插入了 100 行數(shù)據(jù),所以本次的掃描行數(shù)是 100,而進(jìn)行 join 查詢時(shí),對于 t1 表的每一行都需去 t2 表中進(jìn)行查找,走的是索引樹搜索,因?yàn)槲覀儤?gòu)造的數(shù)據(jù)都是一一對應(yīng)的,所以每次搜索只掃描一行,也就是 t2 表也是總共掃描 100 行,整個(gè)查詢過程掃描的總行數(shù)是 100+100=200 行。

無索引查詢過程

SELECT * FROM t1 STRAIGHT_JOIN t2 ON (t1.a = t2.b);
登錄后復(fù)制

簡單聊聊MySQL中join查詢 圖 2

可以看出由于 t2 表字段 B上沒有索引,所以按照上述 SQL 執(zhí)行時(shí)每次從 t1 去匹配 t2 的時(shí)候都要做一次全表掃描,這樣算下來掃描 t2 多大 100 次,總掃描次數(shù)就是 100*1000 = 10 萬行。

當(dāng)然了這個(gè)查詢結(jié)果還是在我們建的這兩個(gè)都是小表的情況下,如果是數(shù)量級 10 萬行的表,就需要掃描 100 億行,這就太恐怖了!

2. 了解 Block Nested-Loop Join

Block Nested-Loop Join查詢過程

那么被驅(qū)動表上沒有存在索引,這一切都是怎么發(fā)生的呢?

實(shí)際上當(dāng)被驅(qū)動表上沒有可用的索引,算法流程是這樣的:

  • 把 t1 的數(shù)據(jù)讀取線程內(nèi)存 join_buffer 中,因?yàn)樯鲜鑫覀儗懙氖?select * from,所以相當(dāng)于是把整個(gè) t1 表放入了內(nèi)存;

  • 掃描 t2 的過程,實(shí)際上是把 t2 的每一行取出來,跟 join_buffer 中的數(shù)據(jù)去做對比,滿足 join 條件的,作為結(jié)果集的一部分進(jìn)行返回。

簡單聊聊MySQL中join查詢

所以結(jié)合圖 2中 Extra 部分說明 Using join buffer 可以發(fā)現(xiàn)這一絲端倪,整個(gè)過程中,對表 t1 和t2 都做了一次全表掃描,因此掃描的行數(shù)是 100+1000=1100 行,因?yàn)?join_buffer 是以無序數(shù)組的方式組織的,因此對于表 t2 中每一行,都要做 100 次判斷,總共需要在內(nèi)存中進(jìn)行的判斷次數(shù)是 100*1000=10 萬次,但是因?yàn)檫@ 10 萬次是發(fā)生在內(nèi)存中的所以速度上要快很多,性能也更好。

Join_buffer

根據(jù)上述已經(jīng)知道了,沒有索引的情況下 MySQL 是將數(shù)據(jù)讀取內(nèi)存進(jìn)行循環(huán)判斷的,那么這個(gè)內(nèi)存肯定不是無限制讓你使用的,這時(shí)我們就需要用到一個(gè)參數(shù) join_buffer_size,該值默認(rèn)大小 256k,如下圖:

SHOW VARIABLES LIKE '%join_buffer_size%';
登錄后復(fù)制

簡單聊聊MySQL中join查詢

圖 4

假如查詢的數(shù)據(jù)過大一次加載不完,只能夠加載部分?jǐn)?shù)據(jù)(80 條),那么查詢的過程就變成了下面這樣

  • 掃描表 t1,順序讀取數(shù)據(jù)行放入 join_buffer 中,直至加載完第 80 行滿了

  • 掃描表 t2,把 t2 表中的每一行取出來跟 join_buffer 中的數(shù)據(jù)做對比,將滿足條件的數(shù)據(jù)作為結(jié)果集的一部分返回

  • 清空 join_buffer

  • 繼續(xù)掃描表 t1,順序讀取剩余的數(shù)據(jù)行放入 join_buffer 中,執(zhí)行步驟 2

這個(gè)流程體現(xiàn)了算法名稱中 Block 的由來,分塊 join,可以看出雖然查詢過程中 t1 被分成了兩次放入 join_buffer 中,導(dǎo)致 t2 表被掃描了 2次,但是判斷等值條件的次數(shù)還是不變的,依然是(80+20)*1000=10 萬次。

所以這就是有時(shí)候 join 查詢很慢,有些大佬會讓你把 join_buffer_size 調(diào)大的原因。

如何正確的寫出 join 查詢

驅(qū)動表的選擇

  • 有索引的情況下

在這個(gè) join 語句執(zhí)行過程中,驅(qū)動表是走全表掃描,而被驅(qū)動表是走樹搜索。

假設(shè)被驅(qū)動表的行數(shù)是 M,每次在被驅(qū)動表查詢一行數(shù)據(jù),先要走索引 a,再搜索主鍵索引。每次搜索一棵樹近似復(fù)雜度是以 2為底的 M的對數(shù),記為 log2M,所以在被驅(qū)動表上查詢一行數(shù)據(jù)的時(shí)間復(fù)雜度是 2*log2M。

假設(shè)驅(qū)動表的行數(shù)是 N,執(zhí)行過程就要掃描驅(qū)動表 N 行,然后對于每一行,到被驅(qū)動表上 匹配一次。因此整個(gè)執(zhí)行過程,近似復(fù)雜度是 N + N2log2M。顯然,N 對掃描行數(shù)的影響更大,因此應(yīng)該讓小表來做驅(qū)動表。

  • 那沒有索引的情況

上述我知道了,因?yàn)?join_buffer 因?yàn)榇嬖谙拗疲圆樵兊倪^程可能存在多次加載 join_buffer,但是判斷的次數(shù)都是 10 萬次,這種情況下應(yīng)該怎么選擇?

假設(shè),驅(qū)動表的數(shù)據(jù)行數(shù)是 N,需要分 K 段才能完成算法流程,被驅(qū)動表的數(shù)據(jù)行數(shù)是 M。這里的 K不是常數(shù),N 越大 K就越大,因此把 K 表示為λ*N,顯然λ的取值范圍 是 (0,1)。

掃描的行數(shù)就變成了 N+λNM,顯然內(nèi)存的判斷次數(shù)是不受哪個(gè)表作為驅(qū)動表而影響的,而考慮到掃描行數(shù),在 M和 N大小確定的情況下,N 小一些,整個(gè)算是的結(jié)果會更小,所以應(yīng)該讓小表作為驅(qū)動表

總結(jié):真相大白了,不管是有索引還是無索引參與 join 查詢的情況下都應(yīng)該是使用小表作為驅(qū)動表。

什么是小表

還是以上面表 t1 和表 t2 為例子:

SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.b = t2.b WHERE t2.id <= 50;  SELECT * FROM t2 STRAIGHT_JOIN t1 ON t1.b = t2.b WHERE t2.id <= 50;
登錄后復(fù)制

上面這兩條 SQL 我們加上了條件 t2.id <= 50,我們使用了字段 b,所以兩條 SQL 都沒有用上索引,但是第二條 SQL 可以看出 join_buffer 只需要放入前 50 行,顯然查詢更快,所以 t2 的前 50 行就是那個(gè)相對較小的表,也就是我們上面說所說的‘小表’。

再看另一組:

SELECT t1.b,t2.* FROM t1 STRAIGHT_JOIN t2 ON t1.b = t2.b WHERE t2.id <= 100;  SELECT t1.b,t2.* FROM t2 STRAIGHT_JOIN t1 ON t1.b = t2.b WHERE t2.id <= 100;
登錄后復(fù)制

這個(gè)例子里,表 t1 和 t2 都是只有 100 行參加 join。 但是,這兩條語句每次查詢放入 join_buffer 中的數(shù)據(jù)是不一樣的: 表 t1 只查字段 b,因此如果把 t1 放到 join_buffer 中,只需要放入字段 b 的值; 表 t2 需要查所有的字段,因此如果把表 t2 放到 join_buffer 中的話,就需要放入三個(gè)字 段 id、a 和 b。

這里,我們應(yīng)該選擇表 t1 作為驅(qū)動表。也就是說在這個(gè)例子里,”只需要一列參與 join 的 表 t1“是那個(gè)相對小的表。

結(jié)論:

在決定哪個(gè)表做驅(qū)動表的時(shí)候,應(yīng)該是兩個(gè)表按照各自的條件過濾,過 濾完成之后,計(jì)算參與 join 的各個(gè)字段的總數(shù)據(jù)量,數(shù)據(jù)量小的那個(gè)表,就是“小表”, 應(yīng)該作為驅(qū)動表。

推薦學(xué)習(xí):mysql視頻教程

贊(0)
分享到: 更多 (0)
網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
gmnon.cn-疯狂蹂躏欧美一区二区精品,欧美精品久久久久a,高清在线视频日韩欧美,日韩免费av一区二区
www.亚洲高清| 91手机视频在线| 日韩精品久久一区二区| 嫩草视频免费在线观看| 亚洲免费av一区| 亚洲激情免费视频| 免费看国产曰批40分钟| av在线无限看| 国产又粗又大又爽的视频| 国产3p露脸普通话对白| 国产精品天天av精麻传媒| 中文字幕第三区| 欧美二区在线视频| 日韩精品在线播放视频| 无码日本精品xxxxxxxxx| 九九热99视频| 黄在线观看网站| 免费观看亚洲视频| 国产一级片91| 两性午夜免费视频| 欧美深夜福利视频| 在线视频一二三区| 今天免费高清在线观看国语| 免费黄频在线观看| 亚洲免费av网| 黄色一级片在线看| 国产精品嫩草影院8vv8| 国产一级特黄a大片免费| 天天夜碰日日摸日日澡性色av| 国产精品99久久久久久大便| 91网址在线观看精品| 日韩va在线观看| 美国av在线播放| 久激情内射婷内射蜜桃| 无码人妻丰满熟妇区毛片18| 亚洲少妇久久久| 亚洲理论电影在线观看| 国产淫片免费看| 欧美第一页浮力影院| 黄色影视在线观看| 自慰无码一区二区三区| 99久久99精品| 欧美在线观看成人| www.偷拍.com| 污污的网站18| 自慰无码一区二区三区| youjizz.com亚洲| 亚洲欧美日韩三级| 97超碰在线人人| 亚洲欧美一区二区三区不卡| 欧在线一二三四区| 欧美三级午夜理伦三级| 欧美一区二区激情| 在线免费观看av网| 在线能看的av网站| 97公开免费视频| 亚洲一二三区av| 激情综合网俺也去| 天天干在线影院| 国产精品拍拍拍| 在线观看免费视频污| 免费涩涩18网站入口| 成年人三级黄色片| 免费看av软件| 日韩av综合在线观看| 熟女性饥渴一区二区三区| 精品视频无码一区二区三区| 国产真实乱子伦| www.色.com| 日韩视频在线视频| 欧美黄色一级片视频| 亚欧美一区二区三区| 欧美日韩亚洲一| 黄色特一级视频| 99sesese| 国产av无码专区亚洲精品| www.-级毛片线天内射视视| 国产极品美女高潮无套久久久| 亚欧在线免费观看| 国产精品999视频| 日本成人xxx| 天天干天天色天天干| www.国产亚洲| 成年丰满熟妇午夜免费视频| 黄大色黄女片18第一次| 精品人妻一区二区三区四区在线 | www亚洲国产| 日日噜噜夜夜狠狠| 水蜜桃色314在线观看| 国产树林野战在线播放| 女同激情久久av久久| 污视频免费在线观看网站| 日本va中文字幕| 在线观看国产中文字幕| 国产精品一区二区小说| 超碰在线免费av| 国内少妇毛片视频| 亚洲国产精品久久久久爰色欲| 91免费国产精品| 欧美成人免费在线观看视频| 18禁免费无码无遮挡不卡网站| 男人操女人免费软件| 亚洲黄色小视频在线观看| 无码无遮挡又大又爽又黄的视频| 成人羞羞国产免费网站| 五月天婷婷亚洲| 妞干网视频在线观看| 九一精品在线观看| 99久久99久久精品| 国产又黄又猛视频| 日本福利视频在线观看| 在线观看高清免费视频| 成人在线免费高清视频| 国内国产精品天干天干| 久久久久99精品成人片| 久久久久xxxx| 日本va中文字幕| aaa毛片在线观看| 欧美成人三级在线视频| 中文字幕超清在线免费观看| 免费黄色福利视频| 成人一级生活片| www国产精品内射老熟女| 日本免费黄色小视频| 免费观看亚洲视频| 欧美日韩dvd| 免费无码国产v片在线观看| 青青草原成人网| 在线看的黄色网址| 国产女教师bbwbbwbbw| 国产精彩视频一区二区| 四季av一区二区| 欧美这里只有精品| 国产无套粉嫩白浆内谢的出处| 少妇高潮喷水在线观看| 久无码久无码av无码| 少妇熟女一区二区| 99久热在线精品视频| 青青视频免费在线观看| 9191国产视频| 三级在线免费观看| 日本免费一级视频| 婷婷视频在线播放| 无码人妻丰满熟妇区毛片18| 狠狠干视频网站| 波多野结衣免费观看| 日本精品一区在线观看| 91亚洲精品久久久蜜桃借种| 99免费视频观看| 日本a√在线观看| 日韩伦理在线免费观看| 精品国产乱码久久久久久1区二区| 青青草视频在线视频| 色七七在线观看| 久久久成人精品一区二区三区 | 中文字幕免费高清在线| 国产96在线 | 亚洲| www.日本少妇| 中文字幕第一页亚洲| 亚洲一级免费观看| 国产又黄又猛视频| 国产精品亚洲二区在线观看| 999一区二区三区| 涩涩网站在线看| 亚洲国产精品女人| 一二三在线视频| 影音先锋成人资源网站| 色噜噜狠狠一区二区三区狼国成人| 久久婷婷国产91天堂综合精品| 天堂中文视频在线| 国产精品动漫网站| 色噜噜狠狠永久免费| 亚洲一区 在线播放| 人妻无码久久一区二区三区免费 | 欧美日韩在线中文| 欧美亚洲日本在线观看| 久久婷五月综合| 无码人妻精品一区二区蜜桃百度| 69精品丰满人妻无码视频a片| av在线网址导航| 国产中文字幕免费观看| 国产视频在线视频| 9久久9毛片又大又硬又粗| aa在线免费观看| 欧美视频第一区| 九九热只有这里有精品| 97av中文字幕| 在线观看中文av| 全黄性性激高免费视频| 亚洲理论中文字幕| 91香蕉视频污版| 国产又大又黄又粗又爽| 黄色一级免费大片| www.亚洲自拍| 久久亚洲中文字幕无码| 黄色aaaaaa| 青青在线视频免费| 91插插插影院| 人妻无码久久一区二区三区免费| 国产免费观看高清视频|