MySQL charset不同导致无法使用索引的坑

今天排查了一个MySQL Charset不同导致无法使用索引的坑。

当然最开始我是不知道的,同事碰到一个性能问题,我也在群里,因此就捞过界了一把,一起看了一下问题。但是从SQL来说应该是 充分利用了SQL才对,所有该有索引的地方都有。原SQL经脱敏简化后如下:

SELECT A.* FROM A LEFT JOIN B ON A.xxx=B.xxx AND B.yyy='yyy' INNER JOIN A AS A_1 ON A.xxx=A1.xxx WHERE A.yyy='yyy';

不过原SQL因为有left join又有inner join,看得我有点晕,于是我直接问原始需求是什么。原来是想看在A表不在B表,所以我改写 成这样:

SELECT A.* FROM A LEFT JOIN B ON A.xxx=B.xxx WHERE B.id IS NULL;

EXPLAIN一下,发现Explain输出里,ref是空,rows却是接近全表的行数,这说明虽然key和extra上表明用上了索引,但实际上没有。 实际执行一下也验证了,确实没有用上索引,查询时间非常久。

逐一检查各表之后,发现该加索引的地方都加了,但是却没有用上索引,最后发现是因为字符集不一样。SHOW CREATE TABLE xxx 之后发现,一张表默认为 utf8,另外一张表默认为 utf8mb4,把字符集都改成utf8mb4之后,就可以正常工作了。


参考链接:


更多文章
  • Linux高分屏支持
  • GCC默认的头文件搜索路径
  • 读《远见-如何规划职业生涯3大阶段》
  • 后端工程师学前端(五): SASS
  • 后端工程师学前端(四): CSS进阶(盒子模型)
  • 读《投资中最简单的事》
  • 后端工程师学前端(三): CSS进阶(特指度、单位和字体族)
  • 后端工程师学前端(二): CSS基础知识(规则与选择器)
  • Swift语法笔记
  • 读《管理的实践》
  • 后端工程师学前端(一): HTML
  • frp 源码阅读与分析(二):TCP内网穿透的实现
  • 五天不用微信 - 爽得很
  • frp 源码阅读与分析(一):流程和概念
  • 学习frp源码之简洁的在两个connection之间转发流量