线上项目,刚开始的时候,数据量比较小,系统性能没有任何问题。随着业务运行时间的增加,数据量会不断的增加,历史数据也会不断累积,这个时候,如果不进行性能优化,系统可能完全无法使用。特别是在数据量达到千万级别以后更是如此。
一个项目中,需要统计一年的账单数据(表中数据在将近1000万),sql执行居然用了将近72秒,整个业务耗时72.6秒。经过针对性的优化,整个业务的处理时间,只需要1.5秒。
slow sql 71652 millis
select merchant_id , count(distinct epay_code) as epay_count, ifnull(count(charge_id),0) as bill_count, ifnull(sum(pay_amt),0) as pay_amt from trans_flow where 1=1 and pay_status = '1' and merchant_id = ? AND epay_code in (SELECT epay_code FROM sys_user_epayitem WHERE user_id=?) and bill_time >= CONCAT(?, ' 00:00:00') and bill_time <= CONCAT(?, ' 23:59:59')["1550000123","109","2018-12-01","2019-12-01"]
业务执行时间:
statisByShop Time Spend is:72615
13:05:25.954 [http-nio-8203-exec-26] INFO c.f.c.s.i.TransFlowServiceImpl - [merchantStatics,220] - \ statisByShop Time Spend is:72615
通过分析,该业务涉及的时间范围广,数据量大,但是需要的数据字段并不多,所以可以针对该业务场景建立针对性的联合索引。
ALTER TABLE `trans_flow` ADD INDEX `union_index` (`merchant_id`, `epay_code`, `pay_amt`, `pay_status`, `bill_time`) USING BTREE ;
慢查询sql已经不再出现。
业务执行时间:
statisByShop Time Spend is:1518
13:23:06.313 [http-nio-8203-exec-1] INFO c.f.c.s.i.TransFlowServiceImpl - [merchantStatics,220] - \ statisByShop Time Spend is:1491
创建联合索引后,再次执行,效率得到明显的提升。主要原因在于原始表的字段多,数据量大,建立联合索引后,该统计业务的所有数据都可以从索引获取,不再需要进行原始表查询了。