MySQL经典SQL优化之字段类型改变影响index merge算法

点击上方“IT那活儿”公众号--专注于企业全栈运维技术分享,不管IT什么活儿,干就完了!!!  


问题描述


某数据库系统历史账单查询sql,由于涉及的表列属性由decimal类型改变为int类型,导致执行计划发生改变。

问题案例:

当该表字段类型为decimal时:

语句执行时间仅为0.014s。语句执行计划为:当字段类型为bigint时:语句执行时间仅为54s。语句执行计划为:

由上可见在decimal字段类型下,优化器自动使用了index_merge算法,虽然都是数字类型,但在bigint字段类型下,优化器却没有选择使用该优化算法。




解决方案


影响优化器执行计划的选择是方方面面的,从官方文档的描述中可以看出在使用INDEX_MERGE优化算法时具有局限性,在AND/OR语句嵌套的情况下,MySQL可能不会选择使用最优方案。

即:

原sql为<br>       SELECT  <em> FROM  t WHERE billing_cycle_id = 202203<br>       AND ( <br>       ( product_instance_id = 65489045484533  ) <br>       OR<br>       ( acct_id = 65489045484533   AND product_instance_id acct_id ) );<br><br>可改写为<br>       SELECT  </em> FROM  t WHERE (billing_cycle_id = 202203<br>       AND  product_instance_id = 65489045484533)<br>OR<br>       ( billing_cycle_id = 202203 <br>       AND<br>       ( acct_id = 65489045484533   AND product_instance_id acct_id ) );<br><br>或者<br>SELECT <em> FROM t<br>WHERE billing_cycle_id = 202109<br>AND product_instance_id = 65489045484533<br>UNION ALL<br>SELECT </em> FROM t<br>WHERE billing_cycle_id = 202109<br>AND acct_id = 65489045484533<br>AND product_instance_id acct_id;

参考:https://dev.mysql.com/doc/refman/5.7/en/index-merge-optimization.html%22%20/t%20%22_blank/

本文作者:拉比克(上海新炬中北团队)

本文来源:“IT那活儿”公众号