偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

MySQL的JOIN到底是怎么玩的

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

高手回答

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

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

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

嵌套循環(huán)算法

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

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

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

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

當無法使用JOIN進行關聯(lián)查詢時,可以考慮使用子查詢、臨時表或者聯(lián)合查詢等方式來實現(xiàn)相同的查詢需求。

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

主要有兩種做法:

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

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

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

MySQL的Hash Join是什么?

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

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

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

舉個例子:

在上述的 left join SQL 中,在進行 Hash Join 過程時,主要包括兩個步驟:構建和探測。

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

圖片圖片

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

圖片圖片

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

基于磁盤的Hash Join

基于磁盤的哈希連接

當驅動表中的數(shù)據(jù)量較大,無法一次性加載到內存中時,就需要考慮將數(shù)據(jù)存儲在磁盤上。通過將哈希表的部分內容存儲在磁盤上,可以分批加載和處理數(shù)據(jù),減少對內存的需求。

在這種算法中,為了避免一個大型哈希表無法完全存儲在內存中,可以采用分表的方法來解決。即通過哈希算法將驅動表分割成多個片段,并將臨時分片寫入磁盤。

這意味著將一個驅動表拆分成多個哈希表,并分別存儲在磁盤上。

圖片圖片

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

圖片圖片

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

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

責任編輯:武曉燕 來源: 碼上遇見你
相關推薦

2019-05-28 13:50:27

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

2024-05-11 09:41:45

線程安全代碼

2020-12-28 08:18:55

安全代碼線程

2022-07-11 08:33:51

容器技術Docker

2019-12-18 18:31:10

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

2016-11-17 22:18:31

id串行化服務器

2024-02-22 08:00:00

SoraOpenAI

2022-08-08 08:00:00

人工智能機器學習計算機應用

2023-07-14 12:21:29

流程@Autowired方法

2022-01-07 07:59:14

Go語言Go Error

2022-01-14 17:01:44

GoError結構

2020-10-19 09:51:18

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

2019-07-23 15:34:29

MySQL存儲引擎

2023-11-16 12:34:00

MySQLjoin

2024-12-09 09:55:25

2022-05-24 17:00:41

區(qū)塊鏈IT比特幣

2022-04-15 08:54:39

PythonAsync代碼

2020-03-05 10:28:19

MySQLMRR磁盤讀

2021-08-02 09:01:05

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

2018-07-30 11:27:12

云服務
點贊
收藏

51CTO技術棧公眾號