mysql 里 delete in 语句暴慢无比 优化

mysql 里 delete in 语句暴慢无比 优化,第1张

十万级别查询量 志强e5 cpu 单核100% 超3分钟才能跑完。

优化后10秒内可以跑完。

思路 通过临时表创建索引用 空间换时间避免频繁读取原表信息

mysql删除原则

not exist 比not in执行效率高 (线上项目保持正确性,没有尝试网上有人推荐使用 not exist 由于改动大没有尝试)

truncate 比 delete执行效率高

实际这里是是一个delete in语句

大概就是这样一个语句,处于preparing 状态,问delete为什么会处于这个状态?

对于preparing状态一般归结为优化阶段,并还没有进入实际的语句执行阶段。但是这里有所不同。并且我们知道一般delete执行慢一般状态会处于,

但是这里是preparing状态。那么为什么会处于这种状态呢?简单分析一下。

我们知道5.7的delete in实际上还是用的DEPENDENT SUBQUERY。这个类似exists的 *** 作,都会用外层查询驱动内层。稍微跟了一下5.7的delete in(不做详细研究),发现所有的query block并没有完全完成优化,实际上这种子查询会在调用Item_subselect::exec的时候通过

进行判断,如果unit->is_optimized()判断为false,则会调入unit->optimize(thd),对subquery的query block进行优化,而优化结束后查询的状态会被设置为preparing。也就出现了这种现象,如下:

这种现象当前看起来是5.7(5.7以下没有测试)中DML语句带in/not in常见的,也可以归结为状态转换稍微考虑欠妥,可能开发大佬也没意识到这个状态已经变为DBA诊断问题的一个主要手段。

而到了8.0状态已经更加精细,有了一些细微的变化,而且8.0.21后支持DML 中的in使用semi join(not in还不行,但是状态是executing)优化。所以我们简单的将其归结为正在执行类似sending data状态即可。需要优化的是将这种delete改写为联合delete形式。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/8672413.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-19
下一篇 2023-04-19

发表评论

登录后才能评论

评论列表(0条)

保存