隐式转换,可以说是关系型数据库SQL优化中很隐秘的问题,之前碰到过很多和他相关的案例,
《Oracle、SQL Server和MySQL的隐式转换异同》
数据和云的这篇文章《SQL优化——隐式字符编码转换》则介绍了MySQL中因为字符集不同导致的隐式转换的问题。
如果对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。
隐式类型转换也会导致放弃走树搜索。
因为类型转换等价于在条件字段上使用了函数,例如,
假设tradeid字段有索引,且为varchar类型,mysql> select * from tradelog where tradeid=110717;等价于,mysql> select * from tradelog where CAST(tradid AS signed int) = 110717;

看执行计划,

从执行计划分析看出问题出在r表也就是h_merge_result_new_indicator表全表扫描,查看该表的表结有联合索引。但是联合索引范围后会失效,于是打算新建一个联合索引,

查看预新建联合索引的字段选择性,

结合选择性来看,
create index idx_hmrni on h_merge_result_new_indicator(keyName,module,BATCH_NO);
创建后,再次看执行计划依然无效,

查看表结构,

另外3个表结构其中有2个utf8mb4,1个utf8,



字符集utf8mb4是utf8的超集,所以当这两个类型的字符串在做比较的时候,MySQL内部的操作是,先将utf8字符串转成utf8mb4字符集,再做比较。因此,



但是还有个问题,如上执行计划key_len是606=(100*3+3)+(100*3+3)。就是说,没有用上BATCH_NO字段上的索引,我们知道索引少一个字段,占用会减少,不会太臃肿。因此,联合索引只需要包含(keyName,module),
drop index idx_hmrni on h_merge_result_new_indicator;create index idx_hmrni on h_merge_result_new_indicator(keyName,module);
近期更新的文章:
《最近碰到的问题》
文章分类和索引:
文章转载自bisal的个人杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




