记录一次踩到MySQL8官方BUG的经历

版权说明: 本文由博主原创,转载请注明出处。
原文地址: https://blog.csdn.net/qq_38688267/article/details/109313764

背景介绍

       前些天完成服务器上云工作,在做数据迁移的是同时也将MySQL5.7.29升级到了MySQL8.0.19。上云工作也写了一篇博客记录:>>传送门<<

       在正式上云之前,我们先同步了一次数据进行测试,排查升级MySQL后出现功能异常的情况。MySQL理论上是向下兼容的,我们也的确没有出现SQL报错等情况。

       但是在上线运营两天后发现有几条类似的SQL的执行效率明显下降。

问题排查

       首先我们来看看是条什么样的SQL吧:

SELECT DISTINCT `区域` FROM `服务单` limit 0,200;

       你没有看错,表名和字段名都是中文!可能有些疾恶如仇的小伙伴情绪瞬间就上来了,容我解释一下:管理这些表的人在我们这的职位是平台数据分析岗,简单来说就是做一些数据报表,业绩/数据月报年报啥的,他们以前都是用EXCEL,所以相当于是以一个小白的身份来操作数据库的,所以对他们来说用起来就行,管它?

       我刚来的时候,也曾提醒过他们,跟他们讲一些表设计的东西啥的,讲得最多的是怎么优化SQL,但是跟他们讲半天,转头还是那样,我就随他们了,反正他们的数据库跟系统的数据库是分开的,随他们弄吧。没想到这次给我挖了这么大一个坑。

       废话就不多说了,我们先来看看SQL的执行计划吧:

在这里插入图片描述
       5.7.298.0.19的执行计划一样,但是5.7.29执行这条SQL只要1.8s8.0.19执行则需要9s。这让我觉得莫名其妙,升级版本后相同的执行计划下MySQL8居然比MySQL5.7慢?

TIPS:
       虽然MySQL8在各方面性能都明显优于低版本;但在某些情况下,MySQL8MySQL5.7-再执行同一条SQL时,可能由于优化器的选择不同,MySQL8执行效率反而低于低版本的。比如MySQL8可能不走索引,而低版本选择走索引等。

       执行计划一样,就说明不是SQL的问题。当然,如果给字段加索引什么的肯定也能提高查询效率,但是我们这次的问题不仅仅是为了解决这一条SQL的慢,好几条SQL都这样,只是表名或字段名不一样。所以我们得找到治本的办法。

尝试解决

       我最先想到的是环境变量,因为这个MySQL8是我新搭的,跟以前的数据库的参数肯定有不同的地方,所以我就一一排查了一遍MySQL的配置。关于影响MySQL性能的环境变量我也写了一篇博客:>>传送门<<

       弄了好一阵,把所有参数有设置成一模一样,稍微好了一点点,执行时间变成了7s,但还远远不够。那么除了环境变量还有啥能改的呢?

       我们再来看看表结构:

在这里插入图片描述
        哦豁!排序规则 不一样!莫不就是这个原因?可把我高兴坏了,就开始测试,换了好几种排序规则,结果发现根本没区别。。。

TIPS:
        MySQL8中增加了几种排序规则,比如utf8mb4utf8mb4_0900_ai_ci,这个规则在MySQL5.7中是不存在的。不同的排序规则对查询SQL有一定影响,比如在没有order by子句的SQL中,不同的排序规则可能返回值顺序不一样。
       在我另外一篇关于 MySQL5.7和8.0索引失效情况整理 的博客中也有提到,不同排序规则的两张表的字段做关联的时候可能会导致索引失效甚至直接报错!>>传送门<<
        千万不要忽略排序规则!

        搞到这里,我实在是想不通还有什么能改的了,我只能认为我安装的时候安装出错了,装了个假MySQL。所以我就把这张表同步到我本地的MySQL8.0.20上面测试,发现还是一样需要7s

        行吧,毕竟windows和Linux可能有区别,我就在云服务器上用Docker又装了个MySQL8.0.20进行测试,发现还是不行。。。

       到此,我意识到这个问题超纲了!~,所以我就到QQ里面的MySQL交流群里面请教,有个大佬帮我弄了半天,他也蒙了,然后他把表数据同步到他本地的MySQL8.0.21中进行测试,居然只要1.6s

       大佬跟我说他的是OK的时候,我的心情是这样的:

在这里插入图片描述

       凭啥?一阵无语后,我也意识到八成是版本的问题了,抱着半信半疑的心态,我又用Docker装了个最新的MySQL8.0.22(Docker镜像中最新),同步数据过去一测,果然!1.6s,是可以的!

       到此,总算是把这个问题解决了!花了我整整两天!这两天我中午都没有休息!别人睡午觉,我在抓耳挠腮!

       翌日,大佬也找到了问题所在:MySQL的官方BUG! 从TempTable存储引擎释放内存时,块大小计算不正确,从而导致SELECT DISTINCT查询性能下降。 这个BUG在MySQL8.0.21中被修复。哇,我好气啊~~~

在这里插入图片描述

相关连接:
       相同问题反馈:https://bugs.mysql.com/bug.php?id=99593
       上图原文地址:https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-21.html

 
       后面又弄了一天,同步数据啥的,这件事总算是弄完了。太难了!几十年的MySQL的BUG都能被我遇到!

       希望本文对大家有所帮助或启发。码字不易,觉得写的不错的可以点赞支持一下哦~

猜你喜欢

转载自blog.csdn.net/qq_38688267/article/details/109313764