mysql环境及表信息
SELECT VERSION(); -- 5.6.28-cdb2016-log
SELECT COUNT(*) FROM T_COLUMN; -- 180
SELECT COUNT(*) FROM BSUSER; -- 500105
SELECT COUNT(*) FROM T_TOPIC; -- 29
问题描述
T_TOPIC和T_COLUMN表分别于BSUSER表做left join查询,两表的记录数及索引相似,但是关联查询语句的执行时间却相差很大。
MySQL在执行join时会把join分为system/const/eq_ref/ref/range/index/ALL等好几类,连接的效率从前往后依次递减。
问题分析及解决
mysql处理多表关联时,当关联列的数据类型和大小相同时,可以更高效的使用列上的索引。当关联列为字符类型时,关联列的字符集如果不同,则不能使用列上的索引。
三个表中的关联字段定义如下
BSUSER:`F_ZGBH` varchar(36) COLLATE gbk_bin NOT NULL DEFAULT ''
T_COLUMN :`F_CREATE_USERID` varchar(36) COLLATE gbk_bin DEFAULT NULL
T_TOPIC:`F_CREATE_USERID` varchar(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL
可以看到BSUSER和T_COLUMN 关联字段的字符集相同,而和T_TOPIC的关联字段的字符集不同,所以出现了“问题描述”中执行计划和执行时间的差异。
修改T_TOPIC的F_CREATE_USERID字段的字符集后,差异消失。