SQL隐式转换导致索引失效_字符集不一致

梦莱2年前技术文章1728

3.字符集不一致导致索引失效

示例 SQL 如下,通过查看执行计划发现 XXX 和 XXXX 表在进行表关联的时候没有走索引,导致 SQL 扫描数量较大。核实表结构发现表关联对应列都存在索引,最终查看字符集发现,两个表的字符集不同存在隐式转换。

--当前SQL
--DB:lefit_live
SELECT ........
FROM XX lu
LEFT JOIN (
SELECT r.*
FROM XXXXX r
WHERE r.is_delete != 1
GROUP BY r.phone
) luw
ON lu.phone = luw.phone
LEFT JOIN XXX luc ON luc.user_id = lu.user_id
LEFT JOIN XXXX lcc ON lcc.channel_code = luc.channel_code
WHERE 1 = 1
AND lu.user_id = 11111
LIMIT 0, 2

查看表结构发现 lcc 表字符集为 utf8,但是 luc 表字符集为 utf8mb4。utf8mb4和utf8两种不同字符集(编码)类型的字符串在做⽐较时,MySQL会先把utf8 字符串转成utf8mb4 字符集,再做⽐较,这就导致了隐式转换的出现。

utf8mb4 是 utf8 的超集,在做隐式⾃动类型转换时,为了避免数据在转换过程中由于截断导致数据错误,会按数据长度增加的⽅向进⾏转换。

该情况可以通过两种方法进行优化。1.修改表字符集。ALTER table 表名 CHARACTER SET 字符集名称;但该方法一般不推荐,首先需要保证该表可以改为 utf8 字符集;其次还要保证修改后,其他使用该表进行表连接的 SQL 不会出现隐式转换问题;且本身 DDL 就是一个比较消耗资源的操作。2.通过修改 SQL 完成优化。可以通过给驱动表关联列加 convert() 函数,使其临时修改成一致的字符集,进行优化。具体改写 SQL 如下:

--改写后
SELECT lu.user_id, lu.phone, lu.nick_name, lu.head_img, lu.gender
, lu.birthday, lu.status, lu.ctime AS reg_time, luc.ctype, luc.channel_code
, lcc.name AS channel_name, luc.source_id, luw.nickname AS wx_nick_name, luw.unionid
FROM XX lu
LEFT JOIN (
SELECT r.*
FROM XXXXX r
WHERE r.is_delete != 1
GROUP BY r.phone
) luw
ON lu.phone = luw.phone
LEFT JOIN XXX luc ON luc.user_id = lu.user_id
LEFT JOIN XXXX lcc ON lcc.channel_code =convert(luc.channel_code USING utf8)
WHERE 1 = 1
AND lu.user_id = 11111
LIMIT 0, 2

--如需修改数据库字符集可以按照如下语句调整
ALTER TABLE biz_circulateitem DEFAULT CHARACTER SET utf8 ;

改写后,表关联列可以正常走上索引,扫描量大大减少。

表连接过程中,被驱动表的索引字段上加函数操作,会导致对被驱动表做全表扫描。因此在进行函数添加时,应选择将驱动表的字符集修改为被驱动表的字符集。


相关文章

CDP实操--Ranger Tag-based策略验证(四)

CDP实操--Ranger Tag-based策略验证(四)

1.1Ranger Tag-based策略验证在Ranger webui里给allan_admin和sam_sec用户赋权,给予添加classification的权限使用allan_admin或者sa...

hdfs数据迁移

hdfs数据迁移

通过使用distcp进行数据全量迁移DistCp(分布式拷贝)是用于大规模集群内部和集群之间拷贝的工具。 它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成。 它把文件和目录的列表作...

从 InnoDB 到 Memory:MySQL 存储引擎的多样性

事务存储引擎是数据库管理系统中负责数据存储、检索和事务处理的组件。它们支持事务的四个基本特性,通常被称为 ACID 属性:原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成,不...

大数据集群部署规划(四)组件建议规格

类型指标名称规格说明HDFS单对NameNode最大文件数1亿-单DataNode最大block数500万GC参数 -Xmx32G单个DataNode磁盘最多block数50万-单个目录下最多文件目录...

mysql 事务隔离级别

mysql 事务隔离级别

一、事务隔离级别介绍多个连接开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个连接在获取数据时的准确性。事务隔离级别      MySQL隔离级别定义了事务与事务之间的隔离程度  二...

Elasticsearch索引慢日志配置

设置索引慢日志各种级别下的阀值,同时也支持多索引(索引名按逗号分隔)和全索引(用*通配符)操作。curl -XPUT --tlsv1.2 --negotiate -k -v -u : 'htt...

发表评论    

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