MySQL优化案例之隐式字符编码转换

 更新时间:2022年07月20日 16:09:28   作者:进击的CJR2  
这篇文章主要介绍了MySQL优化案例之隐式字符编码转换,隐式类型转换也会导致同样的放弃走树搜索,更多相关内容具有一定的参考价值,需要的朋友可以参考一下

索性失效前提

MySQL中我们知道有:

  • 1、如果对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。
  • 2、隐式类型转换也会导致同样的放弃走树搜索。

因为类型转换等价于在条件字段上使用了函数比如:

/*假设tradeid字段有索引,且为varchar类型*/
mysql> select * from tradelog where tradeid=110717;
/*等价于*/
mysql> select * from tradelog where CAST(tradid AS signed int) = 110717;

一个真实的案例

下面来看看隐式字符编码转换导致的一个慢sql

优化前原始sql分析

业务上有个sql执行需要1.31秒

MySQL--SQL优化案例--隐式字符编码转换_联合索引

看看执行计划:

MySQL--SQL优化案例--隐式字符编码转换_mysql_02

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

优化初步处理

MySQL--SQL优化案例--隐式字符编码转换_mysql_03

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

MySQL--SQL优化案例--隐式字符编码转换_mysql_04

结合选择性来看;

create index idx_hmrni on h_merge_result_new_indicator(keyName,module,BATCH_NO);

初步优化无效分析

创建后,再次查看执行计划依然无效;

MySQL--SQL优化案例--隐式字符编码转换_字段_05

查看表结构:

MySQL--SQL优化案例--隐式字符编码转换_mysql_06

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

MySQL--SQL优化案例--隐式字符编码转换_mysql_07

MySQL--SQL优化案例--隐式字符编码转换_联合索引_08

MySQL--SQL优化案例--隐式字符编码转换_字段_09

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

因此:

MySQL--SQL优化案例--隐式字符编码转换_mysql_10

这部分会转换后再与h_merge_result_new_indicator关联

第二次优化处理

优化就只需要将字符集编码转为utf8再和h_merge_result_new_indicator关联就能用上索引

MySQL--SQL优化案例--隐式字符编码转换_联合索引_11

再看查询只需要0.02秒了

MySQL--SQL优化案例--隐式字符编码转换_联合索引_12

第三次优化

但是还有个问题,如上执行计划key_len是606 =(100*3+3)+(100*3+3)

也就是说,没有用上BATCH_NO字段上的索引,我们知道索引少一个字段,占用会减少,不会太臃肿,因此,联合索引只需要包含r(keyName,module)

  • drop index idx_hmrni on h_merge_result_new_indicator;
  • create index idx_hmrni on h_merge_result_new_indicator(keyName,module);

结论

对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。该例子是隐式字符编码转换,它们都跟其他条件索引上使用函数一样,因为要求在索引字段上做函数操作而导致了全索引扫描。

MySQL 的优化器确实有“偷懒”的嫌疑,即使简单地把 where id+1=1000 改写成 where id=1000-1 就能够用上索引快速查找,也不会主动做这个语句重写。

保证在条件索引上不做破坏索引值的有序性,是优化索引的利器。

到此这篇关于MySQL优化案例之隐式字符编码转换的文章就介绍到这了,更多相关MySQL隐式字符编码转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在MySQL中奏响数据库操作的乐章(推荐)

    在MySQL中奏响数据库操作的乐章(推荐)

    本文详细介绍了如何在MySQL中进行数据库操作,包括创建、删除、修改数据库等,以及如何使用字符集和校验规则,以及备份和恢复数据库的方法,同时,还讨论了如何查看和修改数据库的结构和数据,总的来说,本文为读者提供了一份全面的MySQL数据库操作指南
    2024-10-10
  • mysql如何去掉某个字段中的第一个出现的字符串

    mysql如何去掉某个字段中的第一个出现的字符串

    这篇文章主要介绍了mysql如何去掉某个字段中的第一个出现的字符串问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • MySQL 4.0 升级到mysql 5.0的方法

    MySQL 4.0 升级到mysql 5.0的方法

    需要从4.0直接升级到5.0,查看了一下changelog,发现主要有以下变化,需要升级mysql的朋友可以参考下。
    2011-02-02
  • MySQL尾部空格处理方法详解

    MySQL尾部空格处理方法详解

    这篇文章主要介绍了MySQL尾部空格处理方法详解的相关资料,通过创建合适的索引来实现区分有尾部空格和没有尾部空格的字符串,需要的朋友可以参考下
    2023-07-07
  • SQL重复记录查询 查询多个字段、多表查询、删除重复记录的方法

    SQL重复记录查询 查询多个字段、多表查询、删除重复记录的方法

    下面小编就为大家带来一篇SQL重复记录查询 查询多个字段、多表查询、删除重复记录的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • MySQL优化中B树索引知识点总结

    MySQL优化中B树索引知识点总结

    在本文里我们给大家整理了关于MySQL优化中B树索引的相关知识点内容,需要的朋友们可以学习下。
    2019-02-02
  • Linux安装Mysql8.0.20并配置主从复制(一主一从,双主双从)

    Linux安装Mysql8.0.20并配置主从复制(一主一从,双主双从)

    本文主要介绍了Linux安装Mysql8.0.20并配置主从复制,包含一主一从和双主双从,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06
  • MySQL导致索引失效的几种情况

    MySQL导致索引失效的几种情况

    本文主要介绍了MySQL导致索引失效的几种情况,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • MySQL约束(创建表时的各种条件说明)

    MySQL约束(创建表时的各种条件说明)

    这篇文章主要介绍了MySQL约束(创建表时的各种条件说明),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Oracle和MySQL中生成32位uuid的方法举例(国产达梦同Oracle)

    Oracle和MySQL中生成32位uuid的方法举例(国产达梦同Oracle)

    近日遇到朋友问及如何生成UUID,UUID是通用唯一识别码(Universally Unique Identifier)方法,这里给大家总结下,这篇文章主要给大家介绍了关于Oracle和MySQL中生成32位uuid的方法,需要的朋友可以参考下
    2023-08-08

最新评论