新项目业务人员反馈最近下单模块经常卡死,导致锁老是发生,监控观察慢查询和解锁锁后,发现其实只是单个查询慢导致的阻塞锁。在这里,我们首先考虑优化单个查询。一、优化前的表结构、数据量、SQL、执行计划、执行时间1、表结构表A有90个字段,表B有140个字段。2.数据量selectcount(*)fromA;--166713selectcount(*)fromB;--2208103。SQL打开慢查询,观察慢SQL如下,单次执行只用了23秒左右取200条记录。从Aasobwhereifnull(ob.project_code,'')<>''andifnull(ob.accountingitems_code,'')<>''andob.if_cost_proof='N'andEXISTS(select1fromBolwhereob.id=ol.order_base)limit200;4.执行计划思路这两张表是订单表,全国每天大概产生10万行,这里是全量扫描,后期数据到千万级的时候GG完成。目前只看到这条sql上有问题,首先考虑重写exists部分。2.现有部分改写selectob.id,ob.customer,ob.order_no1,ob.accountingitems_code,ob.insert_date,ob.weight,ob.volume,ob.qty,ob.project_code,ob.order_no2,ob.order_type1fromfsl_order_baseasob,fsl_order_base_lineolwhereob.id=ol.order_baseandob.if_cost_proof='N'andifnull(ob.project_code,'')<>''andifnull(ob.accountingitems_code,'')<>''limit200;执行时间:执行需要1.8秒计划:可以看到ob表已经离开了主键索引业务,确认结果满足要求,再在此基础上建索引!3、为ol表创建索引idx_obl_idonfsl_order_base_line(order_base);createindexidx_ob_id_costonfsl_order_base(id,if_cost_proof);如果您不使用该索引,请选择将其删除。4、查看执行时间和执行计划需要1.1秒。不幸的是,执行计划仍然要经过全面扫描。在ob表上建立索引后,实际上并没有使用。最后只是在ol表中建立了索引。5、考虑使用join重写来减少ob结果集,然后做关联搜索,测试是否可以使用索引。选择obc.id,obc.customer,obc.order_no1,obc.accountingitems_code,obc.insert_date,obc.weight,obc.volume,obc.qty,obc.project_code,obc.order_no2,obc.order_type1FROM(select*fromfsl_order_baseASobwhereob.if_cost_proof='N'andifnull(ob.project_code,'')<>''andifnull(ob.accountingitems_code,'')<>'')obcjoinfsl_order_base_lineolonobc.id=ol.order_baselimit200;时间快了一点,但不是很明显,让我们凑合执行计划不变。综上所述,在建索引之前,使用了主键索引,所以耗时1.6秒。建好索引后,并没有使用主键索引,而是使用了ol表的索引,所以是1.5秒,然后缩小结果集进行搜索。就像1s。更重要的是,这两张表一张有90个字段,一张有150个字段,所以后期这两张表关联的结果集应该还是很大的。建议做成分区表。如果桌子可以拆分,那是最好的。不要直接给这些长度这么大,这么宽会对性能有影响。
