使用Ado.net执行SP很慢,而用SSMS执行很快
今天遇到一个问题,有用户反应,在site上打开报表,一直loading,出不来结果。
遇到这种问题,我立刻simulate用户使用Filter Condition,问题repro,看来不是偶然事件,通过SQL Server Profile Capture 到执行的查询语句。
Step1,奇怪的是,在SSMS中执行,SQL Server 很快返回结果,初步结论是问题可能不是由于SQL Server 造成的(事实证明,我错了)。
我的第一反应:是不是network的问题,点击F12,查看Network Tab,全部处于Pending状态,于是,立即发mail联系Fore-End 同事查看。

Leader 看到Mail后,说,这种情况时有发生,通过 sys.dm_exec_requests 能够看到SP正在执行,不可能是Fore-End 和Network 的问题,对SP 进行recompile 后,这个问题就不会出现了。
Step2,于是,我仔细查看 sys.dm_exec_requests,发现这个SP停留在一个大表的Join查询上,logic Read 和 physical read的数量很大,还在持续增加,说明这个SP正在SQL Server上运行,排除了network的问题。尝试对SP进行重新编译,使用以下语句,每次调用sp时都recompile。修改完成之后,果然,报表数据很快就显示出来了。
alter procedure dbo.sp_name
@para int...
with recompile
as .... --RECOMPILE
--Indicates that the Database Engine does not cache a plan for this procedure and the procedure is recompiled at run time.
Step3,SQL Server 为什么会重用拙劣的执行计划?
SQL Server 重用拙劣的执行计划,这就是Parameter Sniffing,Sql server 使用某一个参数生成执行计划,由于该参数不具有代表性,当其他参数重用该执行计划时,其执行效率变得特别慢。
在生成执行计划时,SQL Server根据当前的参数,生成一个适合当前参数的执行计划,该执行计划不一定是最优的,但一定是适合当前参数的,比较优秀的执行计划。由于生成执行计划,比较耗费CPU资源,对于相似的查询语句(query with same shape),SQL Server 会重用执行计划。在重用执行计划时,SQL Server 不会去检查已存的执行计划是否适合当前参数,这就是Parameter Sniffing问题的根源。
可能1,Fore-End调用SqlCommand的Prepare()方法, 创建Prepared Statement,查看DMV:sys.dm_exec_cached_plans,没有发现objtype=Prepared 的Plan cache,说明Fore-End 没有使用预读功能,这其实在一定程度上避免了Parameter Sniffing。
可能2,SQL Server 生成的执行计划是Adhoc Query。查看DMV:sys.dm_exec_cached_plans,发现存在objtype=Adhoc的Plan cache。
结论:SQL Server生成了一个拙劣的执行计划导致这个问题。
在很多关于performance tuning的书籍上都会提到Parameter Sniffing,我也不止一次地对别人说过Parameter Sniffing,终于在Production Environment中遇到Parameter Sniffing问题,还是很兴奋的。遗憾的是,当Parameter Sniffing问题真正出现时,我却没有第一时间识别它,有一丝失落。
Step4,对SP 使用with recompile 选项,太粗暴,推荐的做法是使用 Option Clause
OPTION (OPTIMIZE FOR (@Parameter_Name = N'Typical_Parameter_Value'))
Specifies that the indicated query hint should be used throughout the entire query. Each query hint can be specified only one time, although multiple query hints are permitted. Only one OPTION clause can be specified with the statement.
This clause can be specified in the SELECT, DELETE, UPDATE and MERGE statements.
[ OPTION ( <query_hint> [ ,...n ] ) ]
query_hint
Keywords that indicate which optimizer hints are used to customize the way the Database Engine processes the statement. For more information, see Query Hints (Transact-SQL).
参考Doc:
sys.dm_exec_cached_plans (Transact-SQL)
Optimize Parameter Driven Queries with SQL Server OPTIMIZE FOR Hint
使用Ado.net执行SP很慢,而用SSMS执行很快的更多相关文章
- 腾讯面试:一条SQL语句执行得很慢的原因有哪些?---不看后悔系列
说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你"输入URL回车之后,究竟发生了什么"一样,看看你能说出多少了. 之前腾讯 ...
- 一条SQL语句执行得很慢的原因有哪些?
说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你“输入URL回车之后,究竟发生了什么”一样,看看你能说出多少了. 之前腾讯面试的实话,也问到这 ...
- 一条SQL语句执行得很慢的原因有哪些?(转)
一条 SQL 语句执行的很慢,那是每次执行都很慢呢?还是大多数情况下是正常的,偶尔出现很慢呢?所以我觉得,我们还得分以下两种情况来讨论. 1.大多数情况是正常的,只是偶尔会出现很慢的情况. 2.在数据 ...
- new Random().Next(1, 100); 多线程同时执行结果很高概率相同,
/// <summary> /// new Random().Next(1, 100); 多线程同时执行结果很高概率相同, /// 是用的当前时间为seed,时间相同结果相同 /// // ...
- Security4:授予查看定义,执行SP和只读数据的权限
SQL Server数据库有完善的权限管理机制,对于存储过程,其权限分为查看定义,执行和修改,查看SP定义的权限是:VIEW DEFINITION ,执行存储过程的权限是:EXECUTE,修改SP的权 ...
- 一条SQL语句执行得很慢原因有哪些
一条SQL语句执行得很慢,要分两种情况: 1.大多数情况是正常,偶尔很慢 数据库在处理数据忙时候,更新或新增数据都会暂时记录到redo log日志,等空闲时把数据同步到磁盘.假设数据库一直很忙,更新又 ...
- sql语句执行的很慢
一个 SQL 执行的很慢,我们要分两种情况讨论: 1.大多数情况下很正常,偶尔很慢,则有如下原因 (1).数据库在刷新脏页,例如 redo log 写满了需要同步到磁盘. (2).执行的时候,遇到锁, ...
- 一条SQL语句执行得很慢的原因有哪些?| MySQL高性能优化规范建议
一条SQL语句执行得很慢的原因有哪些 https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485185&idx=1&am ...
- 一条SQL语句执行得很慢的原因有哪些
说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你"输入URL回车之后,究竟发生了什么"一样,看看你能说出多少了. 之前腾讯 ...
随机推荐
- iOS 利用Charles抓包
1.安装 Mac下好用的HTTP/HTTPS抓包工具Charles,到官网http://www.charlesproxy.com/可下载到最新版本(若不支持rMBP可拖到Retinizer中把文字变清 ...
- ACM: Gym 101047E Escape from Ayutthaya - BFS
Gym 101047E Escape from Ayutthaya Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I6 ...
- Basic Calculator II
Implement a basic calculator to evaluate a simple expression string. The expression string contains ...
- javascript获取childNodes详情,删除空节点
chidNodes返回的是node的集合, 每个node都包含有nodeType属性. nodeType取值: 元素节点:1 属性节点:2 文本节点:3 注释节点:8 页面上是由无数个节点组成 ...
- sublime 安装 插件
从菜单 View - Show Console 或者 ctrl + ~ 快捷键,调出 console.将以下 Python 代码粘贴进去并 enter 执行,不出意外即完成安装.以下提供 ST3 和 ...
- 深入浅出HTTP协议(WEB开发和面试必备)
1. 基础概念篇 a.简介 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和 ...
- Bubble Sort (5775)
Bubble Sort Problem Description P is a permutation of the integers from 1 to N(index starting from ...
- Android Intent Flags
Intent,顾名思义,即意图,通常用它来启动一个应用程序组件( Activity, Service, 或者 BroadCast Receiver ).在启动一个新的 Activity 时,可以通过给 ...
- mysql 表表连接的问题。
select * from table a, table b where a.aid = b.bid and aid >100 这样连接,如果a有数据,b没有数据, a.aid = b.bid ...
- 热门的PHP框架
每个PHP框架都拥有各自独特的地方.同时PHP语言已经获得了巨大的认同并且成为了世界上最通用的服务器脚本语言.PHP也俨然成为了最容易学习的web动态开发语言.在PHP发展的同时,PHP框架也迅速崛起 ...