欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Mysql 8.0.18 hash join测试(推荐)

程序员文章站 2022-05-22 13:37:26
hash join hash join 不需要任何索引来执行,并且在大多数情况下比当前的块嵌套循环算法更有效。 下面通过实例代码给大家介绍mysql 8.0.18 hash joi...

hash join

hash join 不需要任何索引来执行,并且在大多数情况下比当前的块嵌套循环算法更有效。

下面通过实例代码给大家介绍mysql 8.0.18 hash join测试,具体内容如下所示:

create table columns_hj as select * from information_schema.`columns`;
insert into columns select * from columns; -- 最后一次插入25万行

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的执行计划:

-> 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秒左右。


再来看bnl,先创建索引(分别优化了,再对比效果才公平)。

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秒。可见hash join效果还是杠杠的。

不得不吐槽下mysql的优化器提示,貌似hash_join/no_hash_join都不生效。

除了hash_join外,mysql 8.0.3引入的set_var优化器提示还是很好用的,可用来设置语句级参数(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

总结

以上所述是小编给大家介绍的mysql 8.0.18 hash join测试,希望对大家有所帮助