成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL的JOIN到底是怎么玩的

數(shù)據(jù)庫(kù) MySQL
MySQL通常采用嵌套循環(huán)(Nested-Loop Join)的方法來(lái)執(zhí)行關(guān)聯(lián)查詢,具體而言,主要包括簡(jiǎn)單嵌套循環(huán)連接(Simple Nested Loop Join)、塊狀嵌套循環(huán)連接(Block Nested Loop Join)和索引嵌套循環(huán)連接(Index Nested Loop Join)這三種算法。

高手回答

在MySQL中,查詢操作通常會(huì)涉及到聯(lián)結(jié)不同表格,而JOIN命令則在這一過(guò)程中扮演了關(guān)鍵角色。在JOIN操作中,我們通常會(huì)使用三種不同的方式,分別是內(nèi)連接、左連接以及右連接。

  • INNER JOIN(內(nèi)連接,或稱為等值連接):此操作獲取了兩個(gè)表中字段相互匹配的記錄,實(shí)質(zhì)上是取得了這兩個(gè)表的交集部分。
  • LEFT JOIN(左連接):相較于內(nèi)連接,左連接獲取了左表格的所有記錄,即便在右表格中可能沒(méi)有對(duì)應(yīng)的匹配記錄。這樣,查詢結(jié)果將包含兩個(gè)表格的交集部分,以及左表格中的所有數(shù)據(jù)。
  • RIGHT JOIN(右連接):右連接與左連接相反,它主要用于獲取右表格中的所有記錄,即便在左表格中找不到對(duì)應(yīng)的匹配數(shù)據(jù)。因此,RIGHT JOIN同樣會(huì)取得兩個(gè)表格的交集部分,以及右表格中的所有數(shù)據(jù)。

在實(shí)施JOIN操作時(shí),還常常會(huì)搭配上關(guān)鍵字ON,用以明確指定關(guān)聯(lián)查詢的一些條件。

嵌套循環(huán)算法

MySQL通常采用嵌套循環(huán)(Nested-Loop Join)的方法來(lái)執(zhí)行關(guān)聯(lián)查詢,具體而言,主要包括簡(jiǎn)單嵌套循環(huán)連接(Simple Nested Loop Join)、塊狀嵌套循環(huán)連接(Block Nested Loop Join)和索引嵌套循環(huán)連接(Index Nested Loop Join)這三種算法。

然而,這三種算法的效率均未能達(dá)到特別的高水平。

  • 簡(jiǎn)單嵌套循環(huán):該算法直截了當(dāng),通過(guò)全面掃描連接兩張表來(lái)進(jìn)行逐一數(shù)據(jù)比對(duì),因此其復(fù)雜度可以被視為N*M,其中N是驅(qū)動(dòng)表的數(shù)量,而M是被驅(qū)動(dòng)表的數(shù)量。
  • 索引嵌套循環(huán):如果內(nèi)循環(huán)表中的字段具有索引,索引嵌套循環(huán)會(huì)利用該索引來(lái)查詢數(shù)據(jù)。由于索引是基于B+樹(shù)的,因此復(fù)雜度近似為N*logM。
  • 塊狀嵌套循環(huán):這種算法引入了一個(gè)緩沖區(qū)(Buffer),它會(huì)提前將外循環(huán)的一部分結(jié)果存放在JOIN BUFFER中,然后內(nèi)循環(huán)中的每一行都與整個(gè)緩沖區(qū)中的數(shù)據(jù)進(jìn)行比較。盡管比較次數(shù)仍為N*M,但由于JOIN BUFFER是基于內(nèi)存的,因此效率大大提高。

盡管MySQL已經(jīng)盡力優(yōu)化這些算法,但這幾種算法的復(fù)雜度仍然相對(duì)較高。這也是為何不建議在數(shù)據(jù)庫(kù)中頻繁進(jìn)行多表JOIN的原因。隨著表格數(shù)量和數(shù)據(jù)量的增加,JOIN操作的效率會(huì)指數(shù)級(jí)下降。

當(dāng)無(wú)法使用JOIN進(jìn)行關(guān)聯(lián)查詢時(shí),可以考慮使用子查詢、臨時(shí)表或者聯(lián)合查詢等方式來(lái)實(shí)現(xiàn)相同的查詢需求。

如果不能通過(guò)數(shù)據(jù)庫(kù)做關(guān)聯(lián)查詢,那么需要查詢多表的數(shù)據(jù)的時(shí)候要怎么做呢?

主要有兩種做法:

  • 在內(nèi)存中自己做關(guān)聯(lián),即先從數(shù)據(jù)庫(kù)中把數(shù)據(jù)查出來(lái)之后,我們?cè)诖a中再進(jìn)行二次查詢,然后再進(jìn)行關(guān)聯(lián)。
  • 數(shù)據(jù)冗余,那就是把一些重要的數(shù)據(jù)在表中做冗余,這樣就可以避免關(guān)聯(lián)查詢了。
  • 寬表,就是基于一定的join關(guān)系,把數(shù)據(jù)庫(kù)中多張表的數(shù)據(jù)打平做一張大寬表,可以同步到ES或者干脆直接在數(shù)據(jù)庫(kù)中直接查都可以

若無(wú)法通過(guò)數(shù)據(jù)庫(kù)進(jìn)行關(guān)聯(lián)查詢,處理涉及多表數(shù)據(jù)的情況,常見(jiàn)的做法有兩種:

  • 在內(nèi)存中自行關(guān)聯(lián):首先從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù),然后在程序中執(zhí)行第二次查詢,隨后進(jìn)行關(guān)聯(lián)操作。
  • 數(shù)據(jù)冗余:通過(guò)在表中存儲(chǔ)一些重要數(shù)據(jù)的冗余副本,可以避免進(jìn)行關(guān)聯(lián)查詢。
  • 寬表設(shè)計(jì):基于一定的連接關(guān)系,將數(shù)據(jù)庫(kù)中多個(gè)表的數(shù)據(jù)打平形成一個(gè)龐大的寬表,這個(gè)寬表可以同步到Elasticsearch(ES),或者直接在數(shù)據(jù)庫(kù)中進(jìn)行查詢操作。

MySQL的Hash Join是什么?

在MySQL 8.0中新增的 Hash Join 算法是一種用于多表連接的算法。在此之前,MySQL通常使用嵌套循環(huán)(Nested-Loop Join)的方法來(lái)執(zhí)行關(guān)聯(lián)查詢,然而嵌套循環(huán)算法在性能方面并不理想。因此,引入了 Hash Join 算法,旨在優(yōu)化 Nested-Loop Join 的性能表現(xiàn)。

所謂的 Hash Join 實(shí)際上底層利用了哈希表。

Hash Join 是針對(duì)等值連接場(chǎng)景的優(yōu)化方法,其基本原則是將驅(qū)動(dòng)表的數(shù)據(jù)加載到內(nèi)存中,并構(gòu)建哈希表,這樣只需遍歷一次非驅(qū)動(dòng)表,然后通過(guò)哈希查找在哈希表中尋找匹配的行,就能完成連接操作。

舉個(gè)例子:

在上述的 left join SQL 中,在進(jìn)行 Hash Join 過(guò)程時(shí),主要包括兩個(gè)步驟:構(gòu)建和探測(cè)。

在構(gòu)建階段中,如果優(yōu)化器經(jīng)過(guò)優(yōu)化選擇了 employee 作為驅(qū)動(dòng)表,那么就會(huì)將該驅(qū)動(dòng)表的數(shù)據(jù)構(gòu)建到哈希表中:

圖片圖片

在探測(cè)階段,當(dāng)從 company 表中取出記錄后,會(huì)到哈希表中查詢匹配的數(shù)據(jù),然后進(jìn)行聚合操作。

圖片圖片

需要注意的是,上述提到的哈希表是存在于內(nèi)存中的。然而,內(nèi)存是有限的(受到 join_buffer_size 的限制)。那么,如果內(nèi)存無(wú)法容納驅(qū)動(dòng)表的數(shù)據(jù)怎么處理呢?那就不得不說(shuō)一說(shuō)基于磁盤(pán)的Hash Join了。

基于磁盤(pán)的Hash Join

基于磁盤(pán)的哈希連接

當(dāng)驅(qū)動(dòng)表中的數(shù)據(jù)量較大,無(wú)法一次性加載到內(nèi)存中時(shí),就需要考慮將數(shù)據(jù)存儲(chǔ)在磁盤(pán)上。通過(guò)將哈希表的部分內(nèi)容存儲(chǔ)在磁盤(pán)上,可以分批加載和處理數(shù)據(jù),減少對(duì)內(nèi)存的需求。

在這種算法中,為了避免一個(gè)大型哈希表無(wú)法完全存儲(chǔ)在內(nèi)存中,可以采用分表的方法來(lái)解決。即通過(guò)哈希算法將驅(qū)動(dòng)表分割成多個(gè)片段,并將臨時(shí)分片寫(xiě)入磁盤(pán)。

這意味著將一個(gè)驅(qū)動(dòng)表拆分成多個(gè)哈希表,并分別存儲(chǔ)在磁盤(pán)上。

圖片圖片

接下來(lái)是進(jìn)行連接操作,在這個(gè)過(guò)程中,對(duì)被驅(qū)動(dòng)表也會(huì)使用相同的哈希算法進(jìn)行分區(qū),以確定在哪個(gè)分區(qū)中。在確定分區(qū)后,首先要確認(rèn)該分區(qū)是否已經(jīng)被加載到內(nèi)存中,如果已加載,則可以直接在內(nèi)存中的哈希表中查找匹配的行。

圖片圖片

如果哈希值對(duì)應(yīng)的分區(qū)尚未加載到內(nèi)存中,則需要從磁盤(pán)上讀取該分區(qū)的數(shù)據(jù)到內(nèi)存中的哈希表,并進(jìn)行匹配。

這樣不斷重復(fù)進(jìn)行,直至完成所有數(shù)據(jù)的連接操作,然后返回結(jié)果集。

責(zé)任編輯:武曉燕 來(lái)源: 碼上遇見(jiàn)你
相關(guān)推薦

2019-05-28 13:50:27

MySQL幻讀數(shù)據(jù)庫(kù)

2024-05-11 09:41:45

線程安全代碼

2020-12-28 08:18:55

安全代碼線程

2022-07-11 08:33:51

容器技術(shù)Docker

2024-02-22 08:00:00

SoraOpenAI

2022-08-08 08:00:00

人工智能機(jī)器學(xué)習(xí)計(jì)算機(jī)應(yīng)用

2023-07-14 12:21:29

流程@Autowired方法

2022-01-07 07:59:14

Go語(yǔ)言Go Error

2022-01-14 17:01:44

GoError結(jié)構(gòu)

2019-12-18 18:31:10

黑客醫(yī)療保險(xiǎn)軟件

2016-11-17 22:18:31

id串行化服務(wù)器

2019-07-23 15:34:29

MySQL存儲(chǔ)引擎

2020-10-19 09:51:18

MYSQL知識(shí)數(shù)據(jù)庫(kù)

2023-11-16 12:34:00

MySQLjoin

2022-04-15 08:54:39

PythonAsync代碼

2024-12-09 09:55:25

2022-05-24 17:00:41

區(qū)塊鏈IT比特幣

2021-08-02 09:01:05

MySQL 多版本并發(fā)數(shù)據(jù)庫(kù)

2020-03-05 10:28:19

MySQLMRR磁盤(pán)讀

2018-02-24 23:19:31

iOSbug蘋(píng)果
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产一区二区三区免费观看在线 | 亚洲第一在线 | 四虎影音| 91久久精品一区二区二区 | 日韩一二区在线 | 国产精品视频在线播放 | 色婷婷综合久久久中字幕精品久久 | 波多野结衣在线观看一区二区三区 | 国产免费一区二区 | 亚洲国产成人在线视频 | 日本超碰 | 欧美第一区 | 国产精品99久久久久久www | 99精品久久久久久久 | 欧美www在线| 91久久国产综合久久 | 毛片一级网站 | 综合精品久久久 | 毛片链接 | 91精品国产91久久综合桃花 | av永久免费| 免费看欧美一级片 | 国产女人叫床高潮大片免费 | 亚洲欧美日韩一区二区 | 国产精品视频一二三区 | 91在线最新 | 红色av社区 | 日韩成人免费视频 | 久久精品国产99国产精品 | 久久综合久 | av黄色在线 | 综合久久综合久久 | h肉视频| 久久国产日韩 | 精品国产黄a∨片高清在线 www.一级片 国产欧美日韩综合精品一区二区 | 久久天堂网 | 日韩久久精品 | 久久男女视频 | 国产精品美女久久久久久久久久久 | 国产欧美一区二区三区在线播放 | 国产一区中文 |