前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL 八怪(高老师)现场解决问题实录

MySQL 八怪(高老师)现场解决问题实录

作者头像
AustinDatabases
发布2024-04-26 13:35:39
990
发布2024-04-26 13:35:39
举报
文章被收录于专栏:AustinDatabasesAustinDatabases

最近感觉,的确是不够用,手指头不够用,群里每天都有有意思的事情,正在准备下一步临时工访谈,一个更有意思刺激的故事,这就遇上群里高老师现场解决问题,高老师是MySQL业界的实战派,出现在群里呢,属于老神仙出山你算不出那天来,估计每天都是忙到想撞墙的地步。

实录开始:

explain format=json

SELECT DISTINCT

b.id,a.sid,a.gid,a.deal1id,a.deal2id,a.deal3id,b.qty,b.costprice,b.costmoney,b.noinqty,b.nooutqty,b.realqty,b.status,a.profileid,b.noreceiveqty,b.norejectqty,

u.fullname ufullname,gu.unitrate,IFNULL(price.refercostprice,'') refercostprice,IFNULL(price.recbuyprice,'') AS recbuyprice,g.enlarge_qty,s.allownegativestock

FROM erp_bill_sale a

LEFT JOIN `erp_goods_stock_deal` b ON a.profileid=b.profileid AND a.sid=b.sid AND a.gid=b.gid AND

a.deal1id=b.deal1id AND a.deal2id=b.deal2id AND a.deal3id=b.deal3id

INNER JOIN bas_goods g ON a.gid = g.gid

INNER JOIN bas_goods_unit gu ON g.gid = gu.gid AND gu.uid=g.saleuid AND a.profileid = gu.profileid AND gu.flag=0

INNER JOIN bas_unit u ON gu.uid = u.uid

INNER JOIN bas_goods_unit curgu ON a.gid=curgu.gid AND curgu.unittype=1 AND a.profileid = curgu.profileid

LEFT JOIN bas_goods_price pr ON pr.gid=a.gid AND pr.deal1id =a.deal1id AND pr.deal2id=a.deal2id AND pr.deal3id=a.deal3id

LEFT JOIN bas_plu plu ON plu.profileid=pr.profileid AND plu.skuid=pr.skuid AND plu.uid=curgu.uid

LEFT JOIN bas_plu_price price ON price.pluid=plu.pluid AND price.profileid=plu.profileid

LEFT JOIN bas_store s ON s.sid = b.sid AND s.profileid=b.profileid

WHERE a.profileid=200007292 AND a.billid = 1066434223 AND plu.flag =0;

语句参见上图,这是群里一个同学提供的,然后这个同学提出语句在执行中出现问题,

1 这个语句单独执行只需要 1秒

2 这个语句放到事务里面需要10分组的样子,才能执行完毕。

这里临时工也稍微的围观和凑合了一下,针对这个同学给出了,事务内和事务外部的TRACE 的文件。(基于隐私和我也没有和这个同学问是否可以把名字 SHOW 出来,只能隐去),这里trace 的文件太大了,我没有办法贴到这里,贴完,估计诸位的手机流量都要爆了。

我就把我昨天,分析这两个TRACE 文件的截图贴上来,方便诸位了解相关的情况。我这里把不一致的部分贴上来。8400多行我也不能都截图,那样电脑也的爆掉,所以只能截取两个语句在比对中不同的部分。

一开始是没有什么不同的,到后面,在行评估的部分开始,就有不同了。这里说梦一下,在各位看官左手的文档是没有事务的,在右手的是在事务中的。

开始出不同了,明显在不在事务内的语句,执行的时候,在使用索引评估时的行部分,有了较大的差异,可以明显看出,在非事务的rows 评估要比事务内的查询语句的 rows 行评估要大一倍,自然COST 也就不一致了

在下面的大部分TRACE 的文件比对的部分,都是有类似的情况,大表基本上行数是没有变化的,所有COST值没有相关的大的变化,而只要涉及到一些ROWS 较小的时候,就会产生较大的差异。

后面我也是是在截图不下去,我才截图5分之一,大部分情况都是这样,到后面整体执行计划部分就都变味了。

到这里结束,其中有一个同学提出,事务隔离级别与锁的问题,导致的执行计划方面的不同。

同时高老师也提出一个问题,关于在事务内,你的事务是否对这些表有变化的问题,比如你删除了表里面的数据,或者UPDATE 或者做其他的操作等。

那个同学回答,是的,的确在事务中有相关的对于表的更改。

整体的问题解决结束。

后面同学又拿出相关的执行计划,下面的是事务外的

这张是事务内的

可以很清晰的看到,相关的索引在两个部分里面选择是不同的。

http://mysql.taobao.org/monthly/2020/03/08/

另外还有一个问题关于这个同学提出的,HINT 部分的问题,高老师也给出图了。

这里补充一些信息,方便不清楚的同学理解, 在MYSQL 中是可以进行HINT的,当多表在进行JOIN 的时候,使用了STRAIGHT_JOINDE 时,MySQL 按照他在查询中的列出的链接顺序链接表,根据不同的链接测量的成本估算对标进行重新的排序,通过straight_join来强制MYSQL按照指定的顺序来进行表的链接顺序的重新制定。

到此为止,整体的事情基本说明白了。

总结一下,

1 事务中,如果查询处于整体事务的下方,同时上方又有相关对查询表的一些数据的修改,那么当达到了一定的表的修改的数量级别,就会对表的统计分析进行变更。

2 在事务中,表的统计分析的数据变更后,整体的执行计划必然会重新调整,如上图,那么就会导致查询计划的变化。出现提出问题同学中关于事务内核事务外部执行同样的语句,但执行的时间的变化。

处理方法是,找到最优的执行方式,并对在事务中执行的查询语句添加HINT 来解决相关的问题。

————————————————————————————

后记:大佬们在解决问题的时候,主要是短平快,他的目的是解决问题,而不是在短时间去分析问题,我们在提问题的时候,应该给付充足的信息如同提出问题的同学,给出的信息比较详细,方便快速定位问题解决问题。

再次感谢 高老师 (八怪)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AustinDatabases 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档