inner join由于字符编码不一致,导致没有走索引

现场反馈有一个sql执行很慢,拿到sql,简化如下所示:

SELECT
sjlz.C_AJBS
FROM
	db_yw.xxx sjlz
	INNER JOIN (
	SELECT
		CONCAT(
			zt.xx,
			zt.xx,
		DATE_FORMAT( zt.DT_FSSJ, '%Y%m%d%H%i%s' )) AS cWybs,
		zt.C_BH 
	FROM
		db_ajm.xx zt 
	WHERE
		x1 NOT LIKE '%22%22%' 
		OR x1 IS NULL 
		LIMIT 0,
		1000 
	) temp ON sjlz.C_AJBS = temp.cWybs 

分析sql, 该sql就是二张表进行inner join ,其中sjlz表是被驱动表,temp表为驱动表。

分析过程

  1. join 之间的优化就在于驱动表和被驱动表,驱动表要设置为小表并且被驱动表应该在关联字段添加索引。

默认的话,驱动表应该是左表,但是mysql会优化,因此会选表小的作为驱动表,因此这里的temp子查询的表就是小表了,sjlz表就是被驱动表了,检查发现sjlz的C_AJBS是添加了索引了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ScRdZDOB-1650421393967)(2)]

  1. 执行explain

也证实了想法,驱动表是temp,被驱动表是sjlz,但是sjlz不走索引,而是进行笛卡尔积的join操作,并且sjlz表大,导致使用了join buffer。

  1. 为啥不走索引呢?

    1. 考虑回表操作,我特意将查询列换成索引列,也不存在回表,因此也不存在说回表导致不走索引
    2. 考虑索引长度,看索引也没有截取长度
  2. 考虑字符集编码
    二个表是属于不同模式下的表,因此可能会存在字符集不相同,
    让运维人员查看了现场环境的sjlz编码,发现确实不一样,sjlz编码是utf, 另一张表编码是uftmb4,因此不走索引是因为字符编码不同所导致。

  3. 证实
    修改表的字符集都为utf8, 执行explain ,ext就显示 using where ; using index;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值