日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Mysql 优化器内部JOIN算法hash join On-Disk Hash Join Grace Hash Join Hybrid hash join过程详解

發(fā)布時間:2024/9/27 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mysql 优化器内部JOIN算法hash join On-Disk Hash Join Grace Hash Join Hybrid hash join过程详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Mysql 各種hash join算法講解

hash join的概述

提到hash join之前自然得說Nest loop join,以兩個表的關(guān)聯(lián)為例,它其實是個雙層循環(huán),先遍歷外層的表(n條),再拿每次對應(yīng)的值去匹配、循環(huán)遍歷內(nèi)部的表(M條)。這樣顯然會有M*n的計算復(fù)雜度。如果能將外部表先裝載到內(nèi)存,然后再做內(nèi)部表的匹配、遍歷,計算的復(fù)雜度就會大大降低,這就是hash join的思想。

本文繼續(xù)介紹hash join的其它幾個算法On-Disk Hash Join、Grace Hash Join、Hybrid hash join。其中In Memory?Join classic hash join的介紹見:

Mysql 優(yōu)化器內(nèi)部JOIN算法hash join Nestloopjoin及classic hash join CHJ過程詳解_數(shù)據(jù)科學(xué)匯集-CSDN博客Mysql hash join之classic hash join CHJ過程詳解hash join的歷史優(yōu)化器里的hash join算法在SQL Server、Oracle、postgress等數(shù)據(jù)庫早已實現(xiàn),而Mysql在8.0.18之后才支持。在8.0.18之前mysql只支持嵌套循環(huán)關(guān)聯(lián)(nested loop join),這其中最簡單就是簡易嵌套循環(huán)關(guān)聯(lián)simple nestloop join,隨后mysql做了改進(jìn)進(jìn)而支持block nestloop join, index nestlohttps://shenliang.blog.csdn.net/article/details/120498088

On-Disk Hash Join

CHJ算法在構(gòu)建表時的內(nèi)存大小可通過參數(shù)join_buffer_size來設(shè)置,但因為需要把整個表都裝到內(nèi)存里,所以這種方法遇到比較大的表時就顯得捉襟見肘。不過也不是沒有方法去規(guī)避,我們按照如下的策略方向做改進(jìn)(分批執(zhí)行的思想,記作):

1 在構(gòu)建哈希表時讀取盡量多的內(nèi)容到內(nèi)存。

2 運行探測過程時讀取整個探測的輸入(即對應(yīng)1里的內(nèi)容)。

3 擦除(清空)內(nèi)存里的哈希表。

4 循環(huán)步驟1里執(zhí)行直至遍歷完構(gòu)建過程里的數(shù)據(jù)。

不過因為需要多次讀取構(gòu)建的輸入(即構(gòu)建表)還是有風(fēng)險且有成本的,假設(shè)構(gòu)建表被分成了n份,那么在匹配探測表時將會掃描n次。這時借助磁盤分區(qū)執(zhí)行的方法on-Disk Hash Join就應(yīng)運而生了。詳細(xì)步驟見下:

Step1:把構(gòu)建表和探測表在磁盤上分成若干小區(qū)(塊),這里分配的原則是每個小區(qū)(塊)能全部裝載到內(nèi)存里,而構(gòu)建表的確定和classic hash join算法類似(一般優(yōu)先選擇小表)。

Step2:當(dāng)所有的記錄都已經(jīng)分區(qū)(塊)到磁盤上的小文件后,開始遍歷分區(qū)(塊),進(jìn)入構(gòu)建階段即將第一個分區(qū)通過函數(shù)函數(shù)裝載到內(nèi)存里形成哈希表,然后在探測階段掃描第一個分區(qū)(塊),該分區(qū)(塊)對應(yīng)構(gòu)建階段里分區(qū)。因為在生成分區(qū)信息時構(gòu)建表和探測表用相同的哈希函數(shù),所以在探測階段進(jìn)行匹配時很容易找到對應(yīng)的分區(qū)信息。

Step3:當(dāng)?shù)谝粋€分區(qū)(塊)處理完了之后清空內(nèi)存里的哈希表,然后把第二個分區(qū)文件裝載到構(gòu)建表,在探測過程用第二個分區(qū)的信息匹配探測表,依次類推直至所有的分區(qū)(塊)都遍歷完。

通過對On-Disk Hash Join的執(zhí)行過程進(jìn)行分析,我們不難發(fā)現(xiàn)該算法會在構(gòu)建過程讀取IO兩次、探測過程寫一次IO。這與開頭里介紹的hash join改善算法(n次IO掃描探測表)已經(jīng)有較大的進(jìn)步。

構(gòu)建表分區(qū)

探測表分區(qū)

構(gòu)建探測兩過程??????

1 in-memory hash join和on-disk hash join算法都是用的msxxHash64作為哈希函數(shù),它是在提供高質(zhì)量的哈希值的同時又能保證快速(減少哈希沖突的數(shù)量)。

2 如果有一個數(shù)據(jù)集傾斜的結(jié)果集會導(dǎo)致構(gòu)建表里的一個分區(qū)(塊)不能填入內(nèi)存,那么hash join算法會按照如下的邏輯處理:

1 讀取盡量多的分區(qū)(塊)到內(nèi)存。

2 在整個探測階段讀取探測分區(qū)。

3 清空內(nèi)存里的哈希表。

4 調(diào)轉(zhuǎn)到步驟1直至構(gòu)建分區(qū)里沒有數(shù)據(jù)。

Grace Hash Join

當(dāng)連接緩存大小(join buffer size)不足時,mysql會先分片再按照classic hash join的方式處理(見On-Disk Hash Join里的注2)。但在極端情況,如果數(shù)據(jù)分布不均勻,有大量數(shù)據(jù)經(jīng)過哈希后分布到一個桶內(nèi),這將導(dǎo)致分片后的連接緩存大小仍然不足。碰到這種情況oracle的grace hash join算法則會繼續(xù)拆分直至有足夠的內(nèi)存可以存放哈希表,當(dāng)然如果在關(guān)聯(lián)條件相同的情況下不論再怎么哈希還是不能拆分時grace hash join也退化為和像mysql一樣先分片再classic hash join的方式處理方式。

Hybrid hash join

如果緩存足夠多的分片數(shù)據(jù)會盡量緩存,那么就不必像GraceHash那樣將所有分片都先讀進(jìn)內(nèi)存,再寫到外存,最后再讀進(jìn)內(nèi)存進(jìn)行build過程,這就是Grace Hash Join算法的核心,即在內(nèi)存相對于分片比較充裕的情況下可以減少磁盤的讀寫IO。目前Oceanbase的HashJoin采用的是這種join方式。

hash join的偽代碼

result = [] join_buffer = [] partitions = 0 on_disk = False for country_row in country:if country_row.Continent == 'Asia':hash = xxHash64(country_row.Code)if not on_disk:join_buffer.append(hash)if is_full(join_buffer):# Create partitions on diskon_disk = Truepartitions = write_buffer_to_disk(join_buffer)join_buffer = []elsewrite_hash_to_disk(hash)if not on_disk:for city_row in city:hash = xxHash64(city_row.CountryCode)if hash in join_buffer:country_row = get_row(hash)city_row = get_row(hash)result.append(join_rows(country_row, city_row))else:for city_row in city:hash = xxHash64(city_row.CountryCode)write_hash_to_disk(hash) for partition in range(partitions):join_buffer = load_build_from_disk(partition)for hash in load_hash_from_disk(partition):if hash in join_buffer:country_row = get_row(hash)city_row = get_row(hash)result.append(join_rows(country_row, city_row)) join_buffer = []

代碼簡介

從country表里讀取每一行并計算code字段對應(yīng)的哈希值并存儲在連接緩存內(nèi)(join buffer)。如果連接緩存滿了則走on-disk算法并哈希后的緩存寫到外部磁盤。也正是在此時分區(qū)的個數(shù)確定,然后對country表剩下的數(shù)據(jù)繼續(xù)哈希。

?對于in-memory的算法只需要通過循環(huán)比較city和緩存里的哈希值即可,而對于on-disk算法哈希的city表會被首先計算并存放在磁盤然后再通過分區(qū)一個個的匹配。

參考:

MySQL :: WL#2241: Hash join

New features of MySQL 8.0 hash join | Develop Paper

總結(jié)

以上是生活随笔為你收集整理的Mysql 优化器内部JOIN算法hash join On-Disk Hash Join Grace Hash Join Hybrid hash join过程详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美日韩中文国产一区发布 | 日本黄色美女视频 | 久久av影院 | 黄色片子网站 | ts人妖另类精品视频系列 | 国产av无码专区亚洲av毛片搜 | 亚洲成人激情小说 | 黑人操中国女人视频 | 亲女禁h啪啪宫交 | 欧美日韩一区在线播放 | 黄色片在线观看视频 | 色小说在线观看 | 国产片天天弄 | 欧美图片一区二区 | 熟妇人妻久久中文字幕 | 亚洲福利影视 | 国内精品在线播放 | 在线成人日韩 | 成人av在线网址 | 美女扒开内裤让男人捅 | 亚洲图片激情小说 | 日韩欧美99 | 一级视频在线免费观看 | 午夜成人亚洲理伦片在线观看 | 涩涩免费网站 | 亚洲欧美另类图片 | 亚洲欧美网址 | 999久久精品 | 国产91精品久久久久久久 | www插插插无码免费视频网站 | 日本一级吃奶淫片免费 | 久久人人爽人人爽人人av | 777精品伊人久久久久大香线蕉 | 8x8ⅹ8成人免费视频观看 | 日日躁夜夜躁aaaabbbb | 成人av影院在线观看 | 大陆农村乡下av | 成人av电影网站 | 奇米精品一区二区三区在线观看一 | 欧美人喂奶吃大乳 | 午夜欧美日韩 | 九九亚洲精品 | 超碰在线最新 | 中文字幕dvd | 国产在线日本 | 一级免费看 | 又黄又色的网站 | 国产亚洲久一区二区 | 美女扒开尿口给男人桶 | 惊艳大片mv视频 | 日本免费a级片 | 欧美午夜网站 | 日韩高清在线观看 | 亚洲欧洲日本精品 | 杨幂毛片| 在线播放www | 亚洲成人中文字幕在线 | 欧美日韩免费做爰视频 | 成人福利影院 | 少妇高清精品毛片在线视频 | jizzjizz国产 | 污视频软件在线观看 | 第四色影音先锋 | 日本a一级 | 中文字幕日韩精品一区 | 精品人妻视频在线 | 日本在线视频一区二区三区 | 免费黄在线 | 啪啪网免费 | 好吊操视频这里只有精品 | 日本一区二区免费看 | 麻豆成人在线观看 | 最新日韩av | 国产精品高潮呻吟久久av野狼 | 亚洲精品传媒 | 国产成人无码性教育视频 | 日本不卡一区二区在线观看 | 最新色网址 | 成人手机视频 | 狠狠操天天射 | 中国女人内谢69xxxx | 国产精品天美传媒入口 | 手机在线播放av | 亚洲欧美日韩一区 | 暖暖日本在线 | 日本在线中文字幕专区 | 在线观看日本 | 天天综合入口 | 亚洲大片免费观看 | 久久日视频 | 国产一级不卡毛片 | 裸体的日本在线观看 | 欧美日韩成人精品 | www.色亚洲| 日本美女啪啪 | 亚洲啪啪网址 | 成人交性视频免费看 | 中文字幕免费中文 | av一区二区三 |