久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL優化器hash?join怎么使用

192次閱讀
沒有評論

共計 2060 個字符,預計需要花費 6 分鐘才能閱讀完成。

今天丸趣 TV 小編給大家分享一下 MySQL 優化器 hash join 怎么使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

前言

數據庫的優化器相當于人類的大腦,大部分時候都能做出正確的決策,制定正確的執行計劃,走出一條高效的路,但是它畢竟是基于某些固定的規則、算法來做的判斷,有時候并沒有我們人腦思維靈活,當我們確定優化器選擇執行計劃錯誤時該怎么辦呢,語句上加 hint,提示它選擇哪條路是一種常見的優化方法。

我們知道 Oracle 提供了比較靈活的 hint 提示來指示優化器在多表連接時選擇哪種表連接方式,比如 use_nl,no_use_nl 控制是否使用 Nest Loop Join,use_hash,no_use_hash 控制是否使用 hash join。

但是 MySQL 長期以來只有一種表連接方式,那就是 Nest Loop Join,直到 MySQL8.0.18 版本才出現了 hash join,所以 MySQL 在控制表連接方式上沒有提供那么多豐富的 hint 給我們使用,hash_join 與 no_hash_join 的 hint 只是驚鴻一瞥,只在 8.0.18 版本存在,8.0.19 及后面的版本又將這個 hint 給廢棄了,那如果我們想讓兩個表做 hash join 該怎么辦呢?

實驗

我們來以 MySQL8.0.25 的單機環境做一個實驗。建兩個表,分別插入 10000 行數據,使用主鍵做這兩個表的關聯查詢。

create table t1(id int primary key,c1 int,c2 int);
create table t2(id int primary key,c1 int,c2 int);
delimiter //
CREATE PROCEDURE p_test()
BEGIN
declare i int;
set i=1;
while i 10001 do
insert into t1 values(i,i,i);
insert into t2 values(i,i,i);
SET i = i + 1;
end while;
delimiter ;

查詢一下兩表使用主鍵字段關聯查詢時實際的執行計劃,如下圖所示:

查詢一下兩表使用非索引字段關聯查詢時實際的執行計劃,如下圖所示:

從執行計劃可以看出,被驅動表的關聯字段上有索引,優化器在選擇表連接方式時會傾向于選擇 Nest Loop Join,當沒有可用索引時傾向于選擇 hash join。

基于這一點那我們可以使用 no_index 提示來禁止語句使用關聯字段的索引。

從上面的執行計劃可以看出使用 no_index 提示后,優化器選擇了使用 hash join。

當索引的選擇性不好時,優化器選擇使用索引做 Nest Loop Join 是效率是很低的。

我們將實驗的兩個表中 c1 列的數據做一下更改, 使其選擇性變差,并在 c1 列上建普通索引。

update t1 set c1=1 where id 5000;
update t2 set c1=1 where id 5000;
create index idx_t1 on t1(c1);
create index idx_t2 on t2(c1);

當我們執行 sql:

select t1.*,t2.* from t1 join t2 on t1.c1=t2.c1;

這個查詢結果會返回大量數據,被驅動表的關聯字段 c1 列的索引選擇性差,此時選擇 hash join 是更明智的選擇,但是優化器會選擇走 Nest Loop Join。我們可以通過實驗驗證一下 hash join 與 Nest Loop Join 的性能差異。

可以看出使用 hash join 的耗時是使用 Nest Loop Join 的 1 /6,但是優化器根據成本估算時,使用 Nest Loop Join 的成本要比使用 hash join 的成本低很多,所以會去選擇 Nest Loop Join,這個時候就需要加上 hint 提示禁止使用關聯字段的索引,被驅動表上每次都全表掃描的代價是很高的,這樣優化器估算后就會選擇走 hash join。

MySQL 官方文檔里提到用 BNL,NO_BNL 的 hint 提示來影響 hash join 的優化,但是經過實驗證明,在表連接關聯字段上沒有可用索引時,優化器估算成本后不會對被驅動表使用 BNL 全表掃描的方式做嵌套循環連接,而是會選擇使用 hash join,那這樣 NO_BNL 在這個場景下就沒有用武之地了。

那么既然不用這個索引,把這個索引去掉不就可以了嗎?為什么非要使用 no_index 的 hint 提示呢,我們要知道業務使用的場景何其多,此處不用,別處使用了這個索引效率可能會有大的提升啊,這個時候就凸顯了 hint 的優勢,只需要控制此語句的使用就好了。

以上就是“MySQL 優化器 hash join 怎么使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,丸趣 TV 小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注丸趣 TV 行業資訊頻道。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-13發表,共計2060字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 浦县| 长寿区| 运城市| 精河县| 邹平县| 唐山市| 海盐县| 饶河县| 马鞍山市| 郴州市| 卫辉市| 洞头县| 顺平县| 祥云县| 洱源县| 平乐县| 光山县| 九龙城区| 江达县| 岳西县| 天祝| 武义县| 青神县| 汤阴县| 光泽县| 平湖市| 龙门县| 定日县| 峨边| 齐齐哈尔市| 四子王旗| 高要市| 博兴县| 苍山县| 蓬溪县| 叶城县| 台中市| 松溪县| 保亭| 双桥区| 柘荣县|