美文网首页
mysql脚本优化实例分享——规避“隐式类型转换”

mysql脚本优化实例分享——规避“隐式类型转换”

作者: joefit | 来源:发表于2018-05-29 16:26 被阅读18次
TIM图片20180529153056.png

内外表exists关联的一条sql,所有字段均建立了索引,外表跟内表是一对多的关系,外表数据量大概在150w,内表的数据量大概在260w,初次执行的时候执行了2分多钟没有返回结果。

查看执行计划,如图中的左侧部分,发现本来是“主外键关联”关系的字段执行计划的类型居然是range(唯一索引等式关联执行计划的类型应该是ref或者const),且内表居然扫描了399284行(exists的语意是拿外表之前过滤后的结果集逐条与内表做关联)。

一开始竟然怀疑是主从库的配置不一样(生产环境只有从库的查询权限),询问DBA得到的反馈是配置是一样的(也是哈,不然主库发生异常,哪敢切从库呢)。

坐下来再次分析sql,一时竟然没有头绪,但是可以肯定的是内表worksheet_code字段应该是没走索引。于是翻看表结构,WTF——居然是varchar类型!这样就很好的解释了执行计划。

那如何去优化这条sql呢?首先想到的自然是把内表的类型修正为bigint,与外表保持一致,但是这种表结构的变更,必然会引起线上系统的报错;而目前只是帮业务导出一批数据,代价太大(后期必须这么做,这个是长久方案)。其次想到的是增加一个bigint的字段,然后把值更新成worksheet_code,这个代价也不小。后来经高人提点——“为啥总是盯着内表字段类型转换呢?”——窗户纸被捅破,是啊,之所以效率低下还不是发生了内表的隐式类型转换嘛

经过优化,sql在2秒多钟就查出了结果,优化过后的执行计划如图右侧部分。

后面还跟高人探讨了exists的使用场景:exists适用于外表结果集小于内表结果集的场景,否则,应该使用in代替exists结果待验证。其实内外表关联的时候,大多是一对多的关系,除非纯粹依靠内表的条件做过滤,否则通常情况下外表的过滤条件结果集一定会小于内表
另外,根据数据库设置情况,or条件的索引不一定会生效,推荐使用in。如本例中原来使用的是opt_type='6' or opt_type='5'.

相关文章

  • mysql脚本优化实例分享——规避“隐式类型转换”

    内外表exists关联的一条sql,所有字段均建立了索引,外表跟内表是一对多的关系,外表数据量大概在150w,内表...

  • MySQL之隐式转换

    MySQL之隐式转换 inexplicit conversion 之前也总给业务优化SQL,隐式转换也非常常见,但...

  • 数据类型转换

    写在前面 C/C++编程中常见数据类型转换,包括隐式类型转换和显式类型转换。 1. 隐式类型转换 隐式类型转换在以...

  • 04_什么是隐式转换?什么是显式转换?

    一、什么是隐式转换? 1.1、隐式转换 隐式类型转换,也称自动类型转换,是指不需要书写代码,由系统自动完成的类型转...

  • Java Script 类型转换以及运算

    (一)类型转换 1、隐式转换 num 被隐式转换为true 2、显式转换 其他数据类型转(布尔类型)1、数字:0和...

  • JavaScript 常见面试题分析(四)

    01 强制类型转换和隐式类型转换 强制:parseInt、parseFloat、toString隐式:if、逻辑运...

  • C++类型转换

    C++的类型转换分为隐式转换和显式转换 隐式转换举例: int i=4; double d=i;//隐式转换 显式...

  • Java 学习笔记_2

    1、隐式转换 和 强制类型转换 隐式转换: 又叫自动类型转换。由系统自动完成的类型转换. 从存储范围小的类型到存储...

  • JavaSE之隐式转换、强制转换

    课前小例 转换类型:隐式转换(自动类型转换)、强制类型转换 隐式转换:两种类型彼此兼容,范围小的类型转成范围大的类...

  • kotlin基础笔记之类型转换

    Kotlin没有隐式拓宽转换,如 Java 中 int 可以隐式转换为 long,必须要显式类型转换。 显式类型转...

网友评论

      本文标题:mysql脚本优化实例分享——规避“隐式类型转换”

      本文链接:https://www.haomeiwen.com/subject/gslajftx.html