mysql8.1和rds性能_相同查询在不同RDS for MySQL的性能差异

本文探讨了在相同查询条件下,RDS for MySQL实例A与实例B性能表现悬殊的情况。问题源于表关联时字段类型不匹配,导致Block Nested Loop的使用。通过调整字段类型和收集统计信息,成功解决了性能问题,强调了遵循开发规范和SQL审核的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【IT168 技术】相同查询在数据量相近的情况下在不同 RDS for MySQL 实例上有不同的性能表现,容易引发用户对 RDS for MySQL 实例的性能差异性的疑虑,本文分享下近期碰到的一个原因比较隐蔽但很常见的案例。

NewArticle.aspx1. 问题出现

一个用户的下述查询在 RDS for MySQL 实例 A 上执行需要 30+ 毫秒,而在 RDS for MySQL 实例 B 执行需要 12+ 秒。

972c948aefd554efdbce8b742d90ca93.png

NewArticle.aspx2. 问题原因

排查 SQL 在 RDS for MySQL 实例 A 和 B 上的执行计划,发现不一致。执行时间短 - A:

762fdca7b6db01f56718f2ae4e810690.png

执行时间长 - B:

3c59d251e8a3ce5261aba9adc2967d1c.png

从执行计划对比看问题出现在 表 A 和 中间表 B 关联这步。

执行计划 B 的 Extra 信息显示 Using join buffer (Block Nested Loop),说明如果选择单纯的 Nested Loop Join 成本会很高(在内层循环无法使用索引的场景下,成本是 O(Rn x Sn))。

优化器为了提高效率,因此选择了 Block Nested Loop。

对比执行计划 A,内层使用的索引是 MySQL 自动创建的(auto_key1),检查优化器开关配置是否有区别,以防万一。

2b2c20f6231abbe55c3808334d3fb6a7.png

对比两个实例优化器开关配置相同,且 materialization 和 subquery_materialization_cost_based 都已经打开, 加之执行计划 B 中有物化表的使用,因此排除掉优化器开关配置问题。

此时问题就比较明朗了,应该是关联的两个字段类型不匹配,导致无法通过索引物化临时表的关联字段来使用 Nested Loop Join。

带着上面的怀疑检查下两个实例的表 Pay 和 inv_msg 的关联字段 PayId 的字段类型。

8e7468c47c0b0512b3aaa5b14157a8f4.png

522a7f5d30bf5cb7b78a663312ead363.png

可以看到 payId 字段在执行快场景下 2 个表都是 big int 类型;而在执行慢的场景下,2个表的字段类型分别为 big int 和 varchar,导致执行计划选择了对无法使用索引场景优化的 Block Netsted Loop。

NewArticle.aspx3. 问题解决

理清问题的根源,就有了针对性的方法。建议用户修改 表 inv_msg 的字段 payid 类型为 big int not null,重新收集统计信息后问题解决。

f8cb63132249fd3cb937ec99636f8f0b.png

NewArticle.aspx4. 问题结论

需要严格遵守规范进行开发工作。

用户 DBA 应该进行 SQL 审核工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值