最近公司计划将风控逻辑移到slave库进行计算,因为考虑到业务表数据会比较大,此时如果还是走nest-loop的话,即使unique进行连接,因为还是需要至少2次以上LIO才能读一条记录,如果达到类似hash join效果的话,在大数据量下,性能通常可以大幅度提升。
因为memory引擎支持hash索引,根据mysql官方文档所述,其基本用途就是K/V存储,内部使用map而非b-tree的实现机制,这样来看,理论上确实达到了hash join的基础。所以,特地做了测试如下:
drop table tb_act_productunitasset_his_test_mem;
create table tb_act_productunitasset_his_test_mem like tb_act_productunitasset_his_test;
delete from tb_act_productunitasset_his_test_mem;
insert into tb_act_productunitasset_his_test_mem select * from tb_act_productunitasset_his_test_mem;
commit;
select count(1) from tb_act_productunitasset_his_test_mem;
在两个表各自的init_date,company_no,unit_code,product_id上包含了非唯一索引,其中XXX_test为btree索引,XXX_test_mem为hash索引。
278432
select u.unit_code,sum(init_asset),sum(original_amt) from tb_act_unitaccount_his u,tb_act_productunitasset_his_test_mem p where u.init_date = p.init_date and u.company_no = p.company_no and u.unit_code = p.unit_code and u.product_id = p.product_id group by u.unit_code
select u.unit_code,sum(init_asset),sum(original_amt) from tb_act_unitaccount_his u,tb_act_productunitasset_his_test p where u.init_date = p.init_date and u.company_no = p.company_no and u.unit_code = p.unit_code and u.product_id = p.product_id group by u.unit_code
从delete、insert来看,memory均性能高倍,因为memory存储的时候直接计算hash值,所以比btree快,这是完全意料中的。
因为测试环境,造实际的业务逻辑比较麻烦,实际业务系统中,可以认为,hash成为unique完全是可以的,比如就算资产表、交易委托表、成交表等都是可以做到的,只不过条件可能是变量值,而不是另外一张关联表而已。
所以,只要DML控制的好同时在mysql启动的时候,通过init-file启动后执行的命令进行初始化加载,很多常用的资料表和当前业务周期表都可以镜像一份memory,在读多写少的系统上,性能提升会非常明显。