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

面試官:MySQL 8.0版本引入的 hash join 有什么優勢?

數據庫 MySQL
MySQL 在 8.0.18 中引入 hash join,這是一個為 join 查詢語句設計的高效算法。今天來介紹一下 hash join。

MySQL 在 8.0.18 中引入 hash join,這是一個為 join 查詢語句設計的高效算法。今天來介紹一下 hash join。

1.簡介

首先我們建立兩張表,SQL 如下:

CREATE TABLE t1 (c1 INT, c2 INT);
CREATE TABLE t2 (c1 INT, c2 INT);

再給出一個連接查詢 SQL:

SELECT * FROM t1 JOIN t2 ON t1.c1=t2.c1;

那 hash join 的執行過程是怎樣的呢?

  •  確定驅動表(MySQL 會選擇結果集較小的表作為驅動表),將結果集加載到內存中;
  •  以連接鍵為 hash key 構建 hash 表,使用鏈表法解決 hash 沖突。 
  • 對于非驅動表,依次掃描每一行數據,對 join 字段取 hash 值,然后在 2 構建的 hash 表中查找這個 hash 值; 
  • 如果找到,則對這個 hash 值所在的鏈表上每個值進行等值比較,如果比較結果一致,則結合兩個表的相關字段生成結果集并輸出; 
  • 如果找不到,則繼續掃描下一行。 整個過程如下圖:

圖片圖片

hash join 的時間復雜度是多少呢?假如 t1 表的記錄數是 M,掃描 t1 表的時間復雜度是 o(M),t2 表的記錄數是 N,掃描 t2 表的時間復雜度是 o(N),hash 表查詢的復雜度是 o(1),這樣使用 hash join 查找的總時間復雜度是 o(M + N)。

2.優勢

在上面的例子中,t1 表和 t2 表都沒有加索引,如果做 join 查詢,在 MySQL 8.0 以前,會使用 BNL 算法。

圖片圖片

BNL 算法流程如下:

  • 把 t1 表的數據讀出放到 join_buffer; 
  • 掃描 t2 表中的每一行,用 c1 字段值跟 join_buffer 中 t1 表的 c1 字段值做比較; 
  • 如果 c1 值一樣,則作為結果集返回,如果不一樣,則繼續掃描 t2 表下一行。

圖片圖片

join_buffer 是一個無序數組,t2 表中的每一行都需要跟 t1 表的所有記錄做比對。假如 t1 表的數據量是 M,t2 表的數據量是 N,則需要比對的次數是 M * N,也就是說時間復雜度是 o(M*N)。

從時間復雜度可以明顯看出 hash join 的優勢。

從 MySQL 8.0.20 開始,不再支持 BNL 算法,server 在原先使用 BNL 算法的地方使用 hash join。

3.hash join 優化

MySQL 8.0.18 引入 hash join,主要用于 join 語句中有等值條件并且 join 條件中不能使用索引的場景。比如前面例子中的 join 語句,t1 和 t2 的 c1 字段都沒有索引:

SELECT * FROM t1 JOIN t2 ON t1.c1=t2.c1;

3.1 配置

MySQL 8.0.18 版本中,支持設置 hash_join=on 或 hash_join=off 供優化器選擇,在 MySQL 8.0.19 及更高版本中,這個設置不再生效,server 會默認使用 hash join。

3.2 連接條件優化

優化一:在 MySQL 8.0.20 以前,如果 join 條件中存在一個非等值匹配的條件,就會走 BNL 算法。MySQL 8.0.20 以后,即使有非等值條件,也會走 hash join。下面 SQL 來自官網:

mysql> EXPLAIN FORMAT=TREE
    -> SELECT * FROM t1
    ->     JOIN t2 ON (t1.c1 = t2.c1)
    ->     JOIN t3 ON (t2.c1 < t3.c1)\G
*************************** 1.row ***************************
EXPLAIN: -> Filter: (t1.c1 < t3.c1)  (cost=1.05rows=1)
    -> Innerhashjoin (no condition)  (cost=1.05rows=1)
        -> Tablescanon t3  (cost=0.35rows=1)
        -> Hash
            -> Innerhashjoin (t2.c1 = t1.c1)  (cost=0.70rows=1)
                -> Tablescanon t2  (cost=0.35rows=1)
                -> Hash
                    -> Tablescanon t1  (cost=0.35rows=1)

優化二:即使 join 沒有條件,也會走 hash join:

mysql> EXPLAIN FORMAT=TREE
    -> SELECT *
    ->     FROM t1
    ->     JOIN t2
    ->     WHERE t1.c2 > 50\G
*************************** 1.row ***************************
EXPLAIN: -> Innerhashjoin  (cost=0.70rows=1)
    -> Tablescanon t2  (cost=0.35rows=1)
    -> Hash
        -> Filter: (t1.c2 > 50)  (cost=0.35rows=1)
            -> Tablescanon t1  (cost=0.35rows=1)

優化三:即使 join 條件中沒有等值條件,也會走 hash join。下面 5 個示例來自官網,都會走 hash join。 

1.內連接無等值條件:

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1 JOIN t2 ON t1.c1 < t2.c1\G
*************************** 1.row ***************************
EXPLAIN: -> Filter: (t1.c1 < t2.c1)  (cost=4.70rows=12)
    -> Innerhashjoin (no condition)  (cost=4.70rows=12)
        -> Tablescanon t2  (cost=0.08rows=6)
        -> Hash
            -> Tablescanon t1  (cost=0.85rows=6)

2.半連接:

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1 
    ->     WHERE t1.c1 IN (SELECT t2.c2 FROM t2)\G
*************************** 1.row ***************************
EXPLAIN: -> Hash semijoin (t2.c2 = t1.c1)  (cost=0.70rows=1)
    -> Tablescanon t1  (cost=0.35rows=1)
    -> Hash
        -> Tablescanon t2  (cost=0.35rows=1)

3.反連接:

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t2 
    ->     WHERE NOT EXISTS (SELECT * FROM t1 WHERE t1.c1 = t2.c1)\G
*************************** 1.row ***************************
EXPLAIN: -> Hash antijoin (t1.c1 = t2.c1)  (cost=0.70rows=1)
    -> Tablescanon t2  (cost=0.35rows=1)
    -> Hash
        -> Tablescanon t1  (cost=0.35rows=1)

1rowinset, 1warning (0.00 sec)

mysql> SHOWWARNINGS\G
*************************** 1.row ***************************
Level: Note
   Code: 1276
Message: Fieldorreference't3.t2.c1'ofSELECT#2 was resolved in SELECT #1

4.左外連接:

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1 LEFTJOIN t2 ON t1.c1 = t2.c1\G
*************************** 1.row ***************************
EXPLAIN: -> Lefthashjoin (t2.c1 = t1.c1)  (cost=0.70rows=1)
    -> Tablescanon t1  (cost=0.35rows=1)
    -> Hash
        -> Tablescanon t2  (cost=0.35rows=1)

5.右外連接:

mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1 RIGHTJOIN t2 ON t1.c1 = t2.c1\G
*************************** 1.row ***************************
EXPLAIN: -> Lefthashjoin (t1.c1 = t2.c1)  (cost=0.70rows=1)
    -> Tablescanon t2  (cost=0.35rows=1)
    -> Hash
        -> Tablescanon t1  (cost=0.35rows=1)

4.總結

hash join 算法的出現對 join 語句的性能大幅提升,MySQL 8.0.20 后,對 hash join 的使用又做了進一步的優化,使用更加便捷。

責任編輯:武曉燕 來源: 君哥聊技術
相關推薦

2025-06-04 07:48:46

2025-03-26 01:25:00

MySQL優化事務

2020-07-02 07:52:11

RedisHash映射

2025-05-14 00:00:00

MySQL雙主架構循環復制

2021-07-06 07:27:45

React元素屬性

2025-04-01 00:00:00

項目CRUD單例模式

2024-08-28 11:58:02

2021-12-20 10:30:33

forforEach前端

2023-02-17 08:10:24

2020-04-03 12:51:21

SQLjoin數據庫

2021-12-10 12:01:37

finalfinallyfinalize

2024-04-03 15:33:04

JWTSession傳輸信息

2024-09-09 08:30:56

代碼

2024-09-19 08:42:43

2021-11-30 07:44:50

FinalFinallyFinalize

2024-04-15 00:01:00

STWJava垃圾

2023-02-20 08:08:48

限流算法計數器算法令牌桶算法

2022-12-27 08:39:54

MySQL主鍵索引

2020-04-23 14:09:13

URI挖坑前端

2021-09-07 10:44:33

Java 注解開發
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩1区2区| 国产高清精品一区二区三区 | 美女黄网| 91在线精品一区二区 | 亚洲一区二区精品视频在线观看 | 久久久青草婷婷精品综合日韩 | 日韩网站在线观看 | 黄色香蕉视频在线观看 | 欧美视频 | 亚洲三区在线观看 | 99久久精品免费看国产免费软件 | 青春草91 | 在线欧美日韩 | 久久综合九色综合欧美狠狠 | 一区二区三区国产视频 | 一级片在线视频 | 久久伊人操| 亚洲国产成人精品在线 | www.亚洲免费| 国产免费一区二区三区最新6 | 亚洲444eee在线观看 | 国产午夜精品一区二区三区在线观看 | 一级黄色夫妻生活 | 中文字幕一区二区三区乱码在线 | 男女视频在线观看网站 | 国产在线观看av | 亚洲精品电影在线观看 | 国产精品网址 | 精品久久久久久久久久久久久久 | 日韩精品免费 | 精品久久久久久一区二区 | 高清一区二区 | 亚洲视频在线一区 | 一区二区免费视频 | 成人深夜福利在线观看 | 国产一二三区电影 | 337p日本欧洲亚洲大胆鲁鲁 | 国产成人在线播放 | 日本一区二区三区在线观看 | 一区二区三区欧美在线观看 | 一级一级毛片免费看 |