首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >产线问题分析与解决系列:3从全表扫描到高效执行-大表连表查询和IN分批次SQL优化实践

产线问题分析与解决系列:3从全表扫描到高效执行-大表连表查询和IN分批次SQL优化实践

作者头像
李福春
发布2025-07-01 19:57:30
发布2025-07-01 19:57:30
800
举报

程序员(小李):负责某核心业务功能的开发。

 运维(老张):负责系统的部署和监控。 

业务方(李总):负责业务需求和上线进度,强调快速扩张。


场景:会议室中,小李、老张和李总正在讨论全境派送运单分拣问题出错的解决方案。

李总(焦急地):小李,老张,这次全境派送的问题很严重啊!面单上的条码和第三方跟踪单号对不上,货物到了中心后,分拣直接瘫痪了。我们的业务扩张速度这么快,这个问题必须马上解决!

小李(认真地):李总,我已经分析了问题的根源。主要是在分拣总包预报的接口中,查询第三方跟踪单号和第三方面单号的SQL关联查询性能太慢,导致数据匹配失败。

老张(点头):对,我也监控到了这个问题。两张大表的关联查询,数据量太大,索引直接失效了。小李,你有什么解决方案吗?

小李:是的,我做了以下优化:

将两张大表的关联查询拆分成两个SQL查询,先查一次表,再组合数据,避免索引失效。

第三方面单号是新加字段,生产数据中很多是空值,导致索引失效。我设置了默认值为空字符串,增加了字段的基数,提升了索引选择性。

发现IN子句中的值在100-200左右时,索引才会生效。所以我将查询分组,每次IN 200条,用上索引提速。

老张(赞许地):这个思路不错!我之前也遇到过类似的问题,IN子句的值太多,优化器直接选择全表扫描了。你这种分批次查询的方式,确实能有效提升性能。

李总(稍微放松):听起来不错,但我们的业务扩张速度很快,数据量会越来越大。这些优化能支撑多久?

小李:李总,这些优化是经过充分测试的,能够支撑当前的数据量。未来如果数据量继续增长,我们可以考虑进一步优化,比如引入缓存机制或者分库分表。

老张:对,我这边也会加强监控,确保系统的稳定性。如果有性能瓶颈,我会第一时间通知小李。

李总(满意地):好,那你们抓紧时间上线这些优化。我们的业务不能停,分拣问题必须尽快解决。

小李:明白,李总。我会尽快完成代码优化和测试,确保不影响业务。

老张:我这边也会配合小李,做好部署和监控工作。

李总(站起身):好,那就辛苦你们了!希望这次优化能彻底解决问题,让我们的业务继续快速扩张!

产生背景

对于全境派送的运单,分拣和派送需要得到面单,面单信息包含:,

1.运单信息;

2.第三方的跟踪单号,

3.其他派送信息

功能上线之后发现:

1.面单上条码跟第三方的跟踪单号对不上;

2.货物到了中心后,中心需要支持扫描第三方,信息不对,没办法分拣;

问题发生节点,分拣总包预报的接口。

逻辑流程:

TrackingNumber匹配运单号——

CustomerNumber匹配运单号——

CustomerNumber匹配参考号——

CustomerNumber匹配第三方跟踪号——

CustomerNumber匹配第三方面单号——

查询第三方跟踪单号和第三方面单号的SQL关联查询性能慢

导致了问题的出现。

解决过程

1:两张大表的关联查询,数量量太大,索引失效。

解决方式:代码改为查两次表,再组合数据;

2:单独查转第三方表,由于第三方面单号为新加字段,生产数据新字段都是空,即便有索引,索引也会失效

解决方式:第三方面单号设置默认=值''空值,索引也不生效

给到dba对应的sql语句,填充历史数据的默认值。

3:生产执行SQL发现IN子句中的值在100-200左右的时候,索引才会生效

解决方式:每次 IN 200条用上索引提速

解决方案

1:两张大表的关联查询分开,一个SQL拆分成两个SQL查询

2:之前SQL查询按照1000条分组多次查询,调整成一组的数量做成可配置的,200条一组查询

3:新加字段第三方面单号设置默认值,增加大表新字段的基数,增加索引选择性

经验总结 

  • 当IN子句中的值超过一定数量(通常是几百个),数据库优化器可能认为全表扫描比使用索引更高效

mysql数据库索引不包含 NULL 值, 使用 in 条件时,全是 NULL 的字段选择性为 0,索引完全失去筛选价值

优化器可能认为全表扫描比使用索引更高效

  • 在数据库优化中,索引的有效使用至关重要,几种索引失效的场景可以避坑

1.使用模糊匹配(如 LIKE %xx 或 LIKE %xx%)时,索引将失效。

2.在查询条件中对索引列应用函数会导致索引失效。

3.对索引列进行表达式计算同样无法使用索引。

4.当字符串与数字进行比较时,MySQL会自动将字符串转换为数字,这种隐式类型转换会导致索引失效。

5.联合索引的使用必须遵循最左匹配原则,否则会导致索引失效。

6.在 WHERE 子句中,如果 OR 前的条件是索引列而 OR 后的条件不是,索引也会失效。

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

本文分享自 李福春持续输出 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档