select * 在存储过程中严重伤性能,因其强制读取传输全部字段、加剧i/o与网络开销,易致执行计划缓存失效及参数嗅探错配,且join顺序错误、事务过大、未显式提交均会放大问题。

为什么 SELECT * 在存储过程中特别伤性能
因为存储过程通常被高频调用,而 SELECT * 会强制数据库读取、传输、解析整行所有字段,哪怕只用其中一两个。尤其当表里有 TEXT、JSON 或大 BLOB 字段时,I/O 和网络开销会指数级上升。
- 明确列出需要的字段,比如把
SELECT *改成SELECT id, name, status - 如果下游应用其实只查
id和name,但表里还有 3 个 2MB 的JSON字段,不改写法等于每次都在搬石头过河 - SQL Server 中,
SELECT *还可能让执行计划缓存失效——列顺序或数量一变,旧计划就作废,触发重复编译
参数嗅探(Parameter Sniffing)导致执行计划“错配”
SQL Server 默认会基于首次传入的参数值生成并缓存执行计划。如果第一次查的是热门用户(返回 10 行),生成了索引查找计划;第二次查冷门用户(返回 50 万行),仍复用该计划,就会慢得离谱。
- 临时方案:在存储过程里加
OPTION (RECOMPILE),比如SELECT ... WHERE user_id = @uid OPTION (RECOMPILE) - 更稳的做法:用局部变量“断开”参数嗅探,如
DECLARE @local_uid INT = @uid; SELECT ... WHERE user_id = @local_uid - 注意:MySQL 和 PostgreSQL 没这问题,但 SQL Server 和 Oracle 用户得绷紧这根弦
JOIN 顺序和驱动表选错,索引全白建
存储过程中多表 JOIN 如果没控制好驱动表(即外层循环表),优化器可能选错执行路径,比如本该用小表驱动大表,结果拿大表做外层,导致嵌套循环次数爆炸。
95Shop可以免费下载使用,是一款仿醉品商城网店系统,内置SEO优化,具有模块丰富、管理简洁直观,操作易用等特点,系统功能完整,运行速度较快,采用ASP.NET(C#)技术开发,配合SQL Serve2000数据库存储数据,运行环境为微软ASP.NET 2.0。95Shop官方网站定期开发新功能和维护升级。可以放心使用! 安装运行方法 1、下载软件压缩包; 2、将下载的软件压缩包解压缩,得到we
- 先看
WHERE条件中哪个表的过滤性最强(比如status = 'active'筛掉 95% 行),让它当驱动表 - 确保驱动表的
JOIN字段上有索引,且类型一致——INT对VARCHAR会导致隐式转换,索引直接失效 - 用
EXPLAIN(MySQL)或SET STATISTICS XML ON(SQL Server)看实际执行计划,别信“应该走索引”这种直觉
事务范围过大,锁住不该锁的资源
存储过程里把一堆无关操作包进一个事务,比如查数据 + 写日志 + 调外部 API + 更新主表,中间任一环节卡住,整个事务就挂着,阻塞其他读写。
- 只把真正需要原子性的语句放进
BEGIN TRANSACTION,比如“扣库存 + 记订单”必须一起成功或失败 - 日志记录、通知类操作尽量挪到事务外,或用异步队列解耦
- 避免在事务里做
WAITFOR DELAY、SLEEP()或调远程 HTTP 接口——这些不是数据库该干的事
最常被忽略的一点:存储过程里没显式 COMMIT 或 ROLLBACK,靠客户端自动提交,一旦连接异常中断,事务可能长期挂起,锁住关键表。写完务必检查每个分支是否都覆盖了事务终点。










