Hash Join
Hash Join 不需要任何索引來(lái)執(zhí)行,并且在大多數(shù)情況下比當(dāng)前的塊嵌套循環(huán)算法更有效。
下面通過(guò)實(shí)例代碼給大家介紹Mysql 8.0.18 hash join測(cè)試,具體內(nèi)容如下所示:
CREATE TABLE COLUMNS_hj as select * from information_schema.`COLUMNS`;
INSERT INTO COLUMNS SELECT * FROM COLUMNS; -- 最后一次插入25萬(wàn)行
CREATE TABLE COLUMNS_hj2 as select * from information_schema.`COLUMNS`;
explain format=tree
SELECT
COUNT(c1. PRIVILEGES),
SUM(c1.ordinal_position)
FROM
COLUMNS_hj c1,
COLUMNS_hj2 c2
WHERE
c1.table_name = c2.table_name
AND c1.column_name = c2.column_name
GROUP BY
c1.table_name,
c1.column_name
ORDER BY
c1.table_name,
c1.column_name;
必須使用format=tree(8.0.16的新特性)才能查看hash join的執(zhí)行計(jì)劃:
-> Sort: temporary>.TABLE_NAME, temporary>.COLUMN_NAME
-> Table scan on temporary>
-> Aggregate using temporary table
-> Inner hash join (c1.`COLUMN_NAME` = c2.`COLUMN_NAME`), (c1.`TABLE_NAME` = c2.`TABLE_NAME`) (cost=134217298.97 rows=13421218)
-> Table scan on c1 (cost=1.60 rows=414619)
-> Hash
-> Table scan on c2 (cost=347.95 rows=3237)
set join_buffer_size=1048576000;
SELECT
COUNT(c1. PRIVILEGES),
SUM(c1.ordinal_position)
FROM
COLUMNS_hj c1,
COLUMNS_hj2 c2
WHERE
c1.table_name = c2.table_name
AND c1.column_name = c2.column_name
GROUP BY
c1.table_name,
c1.column_name
ORDER BY
c1.table_name,
c1.column_name;
1.5秒左右。
再來(lái)看BNL,先創(chuàng)建索引(分別優(yōu)化了,再對(duì)比效果才公平)。
alter table columns_hj drop index idx_columns_hj;
alter table columns_hj2 drop index idx_columns_hj2;
create index idx_columns_hj on columns_hj(table_name,column_name);
create index idx_columns_hj2 on columns_hj2(table_name,column_name);
-> Sort: temporary>.TABLE_NAME, temporary>.COLUMN_NAME
-> Table scan on temporary>
-> Aggregate using temporary table
-> Nested loop inner join (cost=454325.17 rows=412707)
-> Filter: ((c2.`TABLE_NAME` is not null) and (c2.`COLUMN_NAME` is not null)) (cost=347.95 rows=3237)
-> Table scan on c2 (cost=347.95 rows=3237)
-> Index lookup on c1 using idx_COLUMNS_hj (TABLE_NAME=c2.`TABLE_NAME`, COLUMN_NAME=c2.`COLUMN_NAME`) (cost=127.50 rows=127)
大約4.5秒??梢?jiàn)hash join效果還是杠杠的。
不得不吐槽下mysql的優(yōu)化器提示,貌似HASH_JOIN/NO_HASH_JOIN都不生效。
除了hash_join外,mysql 8.0.3引入的SET_VAR優(yōu)化器提示還是很好用的,可用來(lái)設(shè)置語(yǔ)句級(jí)參數(shù)(oracle支持,mariadb記得也支持了的),如下:
mysql> select /*+ set_var(optimizer_switch='index_merge=off') set_var(join_buffer_size=4M) */ c_id from customer limit 1;
SET_VAR支持的變量列表:
auto_increment_increment
auto_increment_offset
big_tables
bulk_insert_buffer_size
default_tmp_storage_engine
div_precision_increment
end_markers_in_json
eq_range_index_dive_limit
foreign_key_checks
group_concat_max_len
insert_id
internal_tmp_mem_storage_engine
join_buffer_size
lock_wait_timeout
max_error_count
max_execution_time
max_heap_table_size
max_join_size
max_length_for_sort_data
max_points_in_geometry
max_seeks_for_key
max_sort_length
optimizer_prune_level
optimizer_search_depth variables
optimizer_switch
range_alloc_block_size
range_optimizer_max_mem_size
read_buffer_size
read_rnd_buffer_size
sort_buffer_size
sql_auto_is_null
sql_big_selects
sql_buffer_result
sql_mode
sql_safe_updates
sql_select_limit
timestamp
tmp_table_size
updatable_views_with_limit
unique_checks
windowing_use_high_precision
總結(jié)
以上所述是小編給大家介紹的Mysql 8.0.18 hash join測(cè)試,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
您可能感興趣的文章:- MySQL聯(lián)表查詢基本操作之left-join常見(jiàn)的坑
- mysql中l(wèi)eft join設(shè)置條件在on與where時(shí)的用法區(qū)別分析
- mysql中各種常見(jiàn)join連表查詢實(shí)例總結(jié)
- MySQL 8.0.18 Hash Join不支持left/right join左右連接問(wèn)題
- MySQL 8.0 新特性之哈希連接(Hash Join)
- MySQL 8.0.18 穩(wěn)定版發(fā)布! Hash Join如期而至
- Mysql巧用join優(yōu)化sql的方法詳解
- MySQL中(JOIN/ORDER BY)語(yǔ)句的查詢過(guò)程及優(yōu)化方法
- 深入理解mysql的自連接和join關(guān)聯(lián)
- Mysql join聯(lián)表及id自增實(shí)例解析