一、参数描述
MySQL中不同的版本优化器会有很多新特性,比如MRR、BKA等,其中optimizer_switch这个参数就是控制查询优化器怎样使用这些特性。很多情况下我们会根据自身的需求去设置optimizer_switch满足我们的需求。
前段时间客户的环境中遇到一个奇怪的问题,select count(*)显示返回是有数据,但select * 返回是空结果集,最终的原因就是因为optimizer_switch设置引起了一个让我们难以察觉的BUG。这里和大家分享一下,希望大家在以后的工作如果遇到类似的问题能够轻松应对。
二、案例分析
2.1 环境描述
数据库版本MySQL5.6.35
2.2 SQL语句
2.3 分析过程
凌晨4点左右客户打来电话告知数据库查询不到数据,显得非常着急,刻不容缓,我们第一时间赶到了现场,当时的现象是这样的:
这条语句查询返回的结果集是空,但是开发人员和我们说数据库中是有数据的,我抱着怀疑的态度尝试着执行了一下:
一看结果当时也有点慌了,count(*)显示返回475条记录,但是select *却返回空结果集……
想了一下SQL语句有一层嵌套,我看看里面这个SQL是否有问题,测试后发现内层语句可以正常返回,加上外层语句时就会出现这种情况。询问了应用人员系统刚迁移过来,在原系统没有这种情况,快速连到原系统上执行同样的语句对比一下两边的执行计划:
原系统
新系统
两边的执行计划不同的地方就是新系统使用了MRR,数据库的版本都是5.6.20之后的小版本号没有相差很多,应该不会出现这种情况。
想到了optimizer_switch这个参数可以设置mrr特性,是不是有人对其做了修改,对比了两边optimizer_switch这个参数发现mrr_cost_based这个值设置的不同。快速的将参数设置为一样再次查询:
立刻就能够返回数据,一切搞定。