MySQL存储过程优化实例

这个存储过程的主要功能是统计指定时间范围内的用户订单汇总数据。先看看最初的核心逻辑是什么样子的:

然后就是经典的游标循环处理:

看起来逻辑挺清晰的,但问题就出在这里。在测试环境用10万条订单数据跑了一下,居然要4.8秒!这完全不能接受。

仔细分析后发现几个明显的性能问题:

首先,在循环内部执行SELECT COUNT(*)来判断记录是否存在,这相当于每处理一条订单都要执行一次查询。10万条订单就是10万次查询,不慢才怪!

其次,游标本身就会带来额外的开销,而且这种逐行处理的方式效率很低。

优化思路很明确:用批量操作代替逐行处理。改写后的核心逻辑是这样的:

这里有个关键点,需要在user_order_summary表上建立唯一索引:

这样就能确保(user_id, summary_date)组合的唯一性,为批量更新创造条件。

另外,原来的查询条件也需要优化。检查发现orders表在order_time字段上没有索引,赶紧加上:

经过这两步优化后,效果立竿见影。同样的数据量,执行时间从4.8秒降到了0.2秒左右,性能提升了20多倍!

这里总结几个存储过程优化的关键点:

避免在循环内执行查询 - 这是最常见的性能杀手

优先考虑集合操作 - 能用一条SQL解决的问题就不要用游标

合理使用索引 - 特别是WHERE条件和JOIN条件的字段

利用批量操作 - 比如INSERT ... ON DUPLICATE KEY UPDATE

减少上下文切换 - 在存储过程中尽量减少SQL语句的执行次数

在实际开发中,游标虽然用起来方便,但性能往往不尽如人意。除非确实需要逐行处理复杂逻辑,否则都应该优先考虑基于集合的操作方式。

另外还要注意,有时候业务逻辑的调整也能带来性能提升。比如这个案例中,如果不需要实时更新汇总数据,可以考虑用定时任务在业务低峰期执行,这样对线上系统的影响会更小。

存储过程优化是个细致活,需要结合具体的业务场景和数据特点来分析。关键是要养成良好的习惯,在写存储过程的时候就要有性能意识,避免留下性能隐患。

相关推荐
ictI CABL15 分钟前
redis连接服务
数据库·redis·bootstrap
苍煜23 分钟前
SpringBoot单体应用到分布式下的数据库锁、事务、Redis事务、分布式锁、分布式事务协调
数据库·spring boot·分布式
xmjd msup1 小时前
mysql的分区表
数据库·mysql
Lyyaoo.1 小时前
【JAVA Spring面经】Spring 事务失效情况
java·数据库·spring
MeAT ITEM1 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
dovens1 小时前
PostgreSQL 中进行数据导入和导出
大数据·数据库·postgresql
IOT.FIVE.NO.11 小时前
claude code desktop cowork报错解决和记录Workspace..The isolated Linux environment ...
linux·服务器·数据库
Rick19931 小时前
mysql 慢查询怎么快速定位
android·数据库·mysql
科技小花8 小时前
全球化深水区,数据治理成为企业出海 “核心竞争力”
大数据·数据库·人工智能·数据治理·数据中台·全球化
X56619 小时前
如何在 Laravel 中正确保存嵌套动态表单数据(主服务与子服务)
jvm·数据库·python