MySQL性能优化(五)字符集不一致导致的隐式类型转换

俊达2年前技术文章942

上一篇文章中,我们介绍了隐式类型转换。这里我们介绍另一种形式的隐式类型转换,由于字符集不一致,导致关联查询无法使用索引。


一个例子

SELECT * 
FROM funds
WHERE  uuid  in ( SELECT uuid FROM patients WHERE create_at != "0000-00-00 00:00:00" )


执行计划



首先优化器对查询做了一个转换,将in查询转换成关联查询

被驱动表funds的uuid上有唯一索引,但是执行计划中显示没有使用索引。


查看执行计划,

explain extended 
    select b.*
    from patients a, funds b
    where a.create_at != "0000-00-00 00:00:00" 
    and a.uuid=b.uuid
    
    
show warnings

select *
from patients a
     join funds b
where((a.create_at <> '0000-00-00 00:00:00')
and(a.uuid= convert(b.uuid using utf8mb4)))


发现对funds.uuid字段进行了类型转换。


我们查看一下表结构的定义,发现uuid的字符集不一致:

 CREATE TABLE `funds` ( 
     `id` int(11) NOT NULL AUTO_INCREMENT,  
     `uuid` varchar(128) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'UUID',
      …,
 PRIMARY KEY (`id`),  
UNIQUE KEY `uuid_idx` (`uuid`),) 
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


CREATE TABLE `patients` ( 
     `id` int(11) NOT NULL AUTO_INCREMENT,  
     `uuid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '项目uuid',  
PRIMARY KEY (`id`),) 
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4


funds.uuid 是utf8,而patients.uuid是utf8mb4。



我们在SQL中做一个处理,将驱动表的uuid字段字符集转换成utf8,匹配被驱动表的uuid字符集:

explain extended
 SELECT b.*
FROM (select convert(uuid using utf8) COLLATE utf8_unicode_ci as uuid
    from patients 
    where project_create_at != "0000-00-00 00:00:00") a, funds b
WHERE a.uuid = b.uuid


5-2.jpg


对SQL进行改写之后,可以看到,可以使用uuid字段上的索引。解决了查询的性能问题。


总结

同一个业务字段,在不同的表中数据类型和字符集要保持一致。这样可以避免表关联的时候发生隐式类型转换。

相关文章

MySQL 自动化部署 5.6版本

MySQL 自动化部署 5.6版本

一、脚本环境说明系统:CentOS 7MySQL:该脚本只支持安装 MySQL 5.6 GA 版本如有问题可以联系:文若 wenruo@dtstack.com脚本默认安装路径 /usr/local/m...

prometheus黑盒监控

prometheus黑盒监控

黑盒监控即以用户的身份测试服务的外部可见性,常见的黑盒监控包括 HTTP探针、TCP探针、Dns、Icmp等用于检测站点、服务的可访问性、服务的连通性,以及访问效率等。prometheus提供了bla...

win内存使用率过高但是资源监视器查看不到进程,排查思路

win内存使用率过高但是资源监视器查看不到进程,排查思路

问题现象:服务器:某云服务器 内存使用率持续打高,但是通过任务管理器查不到占用内存很高的进程排查步骤:1、通过任务管理器分析核查目标主机的内存使用趋势情况,近7天内存使用情况如下:通过任务管理器排查内...

SpringBootWeb 篇-深入了解 SpringBoot + Vue 的前后端分离项目部署上线与 Nginx 配置文件结构(4)

SpringBootWeb 篇-深入了解 SpringBoot + Vue 的前后端分离项目部署上线与 Nginx 配置文件结构(4)

 6.0 nginx 配置文件结构        6.1 先了解以下配置文件的结构Nginx 文件结构:      &n...

MySQL 8.0 新特性:Descending Indexes

MySQL 8.0 新特性:Descending Indexes

一、前言MySQL 8.0 之前的索引排序规则之前只允许 ASC 存储,创建时指定 DESC 也会被忽略,8.0 版本为我们带来了 Descending Indexes 降序索引 👏👏👏只能使用 AS...

hive部署

安装前准备修改环境变量vi /etc/profile 添加内容如下:(hive节点都要执行)export HIVE_HOME=/opt/hiveexport PATH=$PATH:$HIVE_HOME...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。