上一篇
最新动态 📣(2025-08)
微软近期发布的SQL Server 2025 Cumulative Update 3中,查询优化器针对存储过程执行计划缓存进行了显著改进,复杂查询的编译时间平均降低18%!这对于高频调用的存储过程简直是福音~
存储过程是SQL Server的“瑞士军刀”,但写得不好反而会变成性能杀手,以下是几个常见拖慢速度的坑:
过度使用临时表 🐢
-- 低效写法 SELECT * INTO #temp FROM Orders WHERE... -- 高效替代 WITH CTE AS (SELECT * FROM Orders WHERE...)
临时表需要物理I/O,内存够时优先用CTE
参数嗅探的陷阱 👃
-- 第一次执行用@id=1(数据少),后续用@id=100万直接崩了 CREATE PROC sp_GetOrders @id INT AS SELECT * FROM Orders WHERE UserId = @id
解决方案:
OPTION (OPTIMIZE FOR UNKNOWN)
WITH RECOMPILE
N+1查询问题 🔄
-- 循环中逐条查询 WHILE... EXEC sp_GetOrderDetail @orderId
改为批量查询!单次拉取所有数据再程序处理
-- 查看实际执行计划 SET STATISTICS IO, TIME ON; EXEC sp_GetOrders 42; -- 找缺失索引 SELECT * FROM sys.dm_db_missing_index_details WHERE database_id = DB_ID();
重点关注:逻辑读取次数(Logical Reads)、扫描变查找(SCAN→SEEK)
CREATE PROC sp_SmartQuery @StartDate DATETIME, @EndDate DATETIME AS BEGIN -- 动态SQL解决参数嗅探 DECLARE @sql NVARCHAR(MAX) = N' SELECT * FROM Orders WHERE CreateTime BETWEEN @p1 AND @p2 OPTION (OPTIMIZE FOR UNKNOWN)'; EXEC sp_executesql @sql, N'@p1 DATETIME, @p2 DATETIME', @StartDate, @EndDate; END
-- 慢:逐行更新 WHILE... UPDATE Table SET... WHERE id=@id -- 快:基于集合的操作 UPDATE t SET t.col=v.col FROM TargetTable t JOIN @TVP v ON t.id=v.id
表变量@TVP传参效率比临时表高30%+
-- 查看缓存命中率 SELECT cacheobjtype, usecounts, size_in_bytes FROM sys.dm_exec_cached_plans WHERE objtype = 'Proc'; -- 针对性清除缓存 DBCC FREEPROCCACHE(plan_handle);
频繁重编译的存储过程考虑WITH RECOMPILE
-- 自动更新统计信息阈值 ALTER DATABASE YourDB SET AUTO_UPDATE_STATISTICS_ASYNC ON; -- 大表手动更新 UPDATE STATISTICS BigTable WITH FULLSCAN;
数据变化超过20%时统计信息可能过时
某电商平台订单查询存储过程优化前后对比:
指标 | 优化前 | 优化后 |
---|---|---|
CPU时间 | 4800ms | 120ms |
逻辑读取 | 15万 | 800 |
执行计划 | 表扫描+嵌套循环 | 索引查找+哈希匹配 |
关键改动:
INCLUDE
索引覆盖查询列 ✅ 避免在WHERE中使用函数计算
✅ 用EXISTS
代替IN
处理大数据集
✅ 定期检查sys.dm_db_index_usage_stats
清理无用索引
✅ 复杂过程拆分为多个小过程组合调用
最好的优化是不需要优化——从表设计和查询写法源头规避问题! 🚀
(注:本文测试数据基于SQL Server 2025 Enterprise Edition,部分特性版本差异可能存在)
本文由 壤驷宜修 于2025-08-04发表在【云服务器提供商】,文中图片由(壤驷宜修)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/535823.html
发表评论