自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL的JOIN到底是怎么玩的

數(shù)據(jù)庫(kù) MySQL
MySQL通常采用嵌套循環(huán)(Nested-Loop Join)的方法來執(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ān)鍵角色。在JOIN操作中,我們通常會(huì)使用三種不同的方式,分別是內(nèi)連接、左連接以及右連接。

  • INNER JOIN(內(nèi)連接,或稱為等值連接):此操作獲取了兩個(gè)表中字段相互匹配的記錄,實(shí)質(zhì)上是取得了這兩個(gè)表的交集部分。
  • LEFT JOIN(左連接):相較于內(nè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)的方法來執(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),通過全面掃描連接兩張表來進(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ì)利用該索引來查詢數(shù)據(jù)。由于索引是基于B+樹的,因此復(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)合查詢等方式來實(shí)現(xiàn)相同的查詢需求。

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

主要有兩種做法:

  • 在內(nèi)存中自己做關(guān)聯(lián),即先從數(shù)據(jù)庫(kù)中把數(shù)據(jù)查出來之后,我們?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ú)法通過數(shù)據(jù)庫(kù)進(jìn)行關(guān)聯(lián)查詢,處理涉及多表數(shù)據(jù)的情況,常見的做法有兩種:

  • 在內(nèi)存中自行關(guān)聯(lián):首先從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù),然后在程序中執(zhí)行第二次查詢,隨后進(jìn)行關(guān)聯(lián)操作。
  • 數(shù)據(jù)冗余:通過在表中存儲(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)的方法來執(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)表,然后通過哈希查找在哈希表中尋找匹配的行,就能完成連接操作。

舉個(gè)例子:

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

在構(gòu)建階段中,如果優(yōu)化器經(jīng)過優(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ù)怎么處理呢?那就不得不說一說基于磁盤的Hash Join了。

基于磁盤的Hash Join

基于磁盤的哈希連接

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

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

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

圖片圖片

接下來是進(jìn)行連接操作,在這個(gè)過程中,對(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)存中,則需要從磁盤上讀取該分區(qū)的數(shù)據(jù)到內(nèi)存中的哈希表,并進(jìn)行匹配。

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

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

2019-05-28 13:50:27

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

2020-12-28 08:18:55

安全代碼線程

2024-05-11 09:41:45

線程安全代碼

2022-01-07 07:59:14

Go語(yǔ)言Go Error

2022-01-14 17:01:44

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

2023-07-14 12:21:29

流程@Autowired方法

2019-07-23 15:34:29

MySQL存儲(chǔ)引擎

2019-12-18 18:31:10

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

2016-11-17 22:18:31

id串行化服務(wù)器

2022-07-11 08:33:51

容器技術(shù)Docker

2020-10-19 09:51:18

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

2023-11-16 12:34:00

MySQLjoin

2022-08-08 08:00:00

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

2024-02-22 08:00:00

SoraOpenAI

2022-04-15 08:54:39

PythonAsync代碼

2024-12-09 09:55:25

2021-08-02 09:01:05

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

2022-05-24 17:00:41

區(qū)塊鏈IT比特幣

2020-03-05 10:28:19

MySQLMRR磁盤讀

2018-09-30 15:05:01

Linux用戶組命令
點(diǎn)贊
收藏

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