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

俊达2年前技术文章681

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


一个例子

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字段上的索引。解决了查询的性能问题。


总结

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

相关文章

等待事件latch: cache buffers chains 的分析与优化

等待事件latch: cache buffers chains 的分析与优化

等待事件latch: cache buffers chains 的分析与优化要理解latch: cache buffers chains并解决这个问题,就需要深入的了解Buffer Cach...

Shell中单引号和双引号区别

1)在/home/atguigu/bin创建一个test.sh文件[atguigu@hadoop102 bin]$ vim test.sh在文件中添加如下内容#!/bin/bashdo_date=$1...

Kafka Rebalance详解

1.rebalance概览rebalance中文含义为再平衡。它本质上是一组协议,它规定了一个 consumer group 是如何达成一致来分配订阅 topic 的所有分区的。比方说Consumer...

SQL Server优化入门系列(四)——  找到Top SQL

SQL Server优化入门系列(四)—— 找到Top SQL

说明从会话信息中我们可以查看实例当前正在运行的SQL、当前被Block的SQL。但是如果要查看过去一段时间执行的SQL,我们有几个选择1、通过外部SQL审计平台记录所有SQL。2、通过SQL Serv...

grafana常见问题处理

grafana常见问题处理

发现了一个不错的grafana模版,下载安装后很多问题,需要处理后才能使用。第一个问题就是显示插件不存在。插件未找到问题处理安装插件并重启既然未找到插件,那我们肯定要安装下插件,使用grafana-c...

ip_foward未开启导致slb健康检查异常

ip_foward未开启导致slb健康检查异常

现象:在slb上配置一条7层http监听,并开启健康检查,发现健康检查一直异常。处理步骤:针对slb健康检查异常的问题,可从以下四个方面入手,排查原因。1、确认服务器上业务程序正常启动,且在后端服务器...

发表评论    

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