今天遇到一个问题,有用户反应,在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'))

Option Clause

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:

I Smell a Parameter!

sys.dm_exec_cached_plans (Transact-SQL)

OPTION Clause (Transact-SQL)

Parameter Sniffing

Optimize Parameter Driven Queries with SQL Server OPTIMIZE FOR Hint

使用Ado.net执行SP很慢,而用SSMS执行很快的更多相关文章

  1. 腾讯面试:一条SQL语句执行得很慢的原因有哪些?---不看后悔系列

    说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你"输入URL回车之后,究竟发生了什么"一样,看看你能说出多少了. 之前腾讯 ...

  2. 一条SQL语句执行得很慢的原因有哪些?

    说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你“输入URL回车之后,究竟发生了什么”一样,看看你能说出多少了. 之前腾讯面试的实话,也问到这 ...

  3. 一条SQL语句执行得很慢的原因有哪些?(转)

    一条 SQL 语句执行的很慢,那是每次执行都很慢呢?还是大多数情况下是正常的,偶尔出现很慢呢?所以我觉得,我们还得分以下两种情况来讨论. 1.大多数情况是正常的,只是偶尔会出现很慢的情况. 2.在数据 ...

  4. new Random().Next(1, 100); 多线程同时执行结果很高概率相同,

    /// <summary> /// new Random().Next(1, 100); 多线程同时执行结果很高概率相同, /// 是用的当前时间为seed,时间相同结果相同 /// // ...

  5. Security4:授予查看定义,执行SP和只读数据的权限

    SQL Server数据库有完善的权限管理机制,对于存储过程,其权限分为查看定义,执行和修改,查看SP定义的权限是:VIEW DEFINITION ,执行存储过程的权限是:EXECUTE,修改SP的权 ...

  6. 一条SQL语句执行得很慢原因有哪些

    一条SQL语句执行得很慢,要分两种情况: 1.大多数情况是正常,偶尔很慢 数据库在处理数据忙时候,更新或新增数据都会暂时记录到redo log日志,等空闲时把数据同步到磁盘.假设数据库一直很忙,更新又 ...

  7. sql语句执行的很慢

    一个 SQL 执行的很慢,我们要分两种情况讨论: 1.大多数情况下很正常,偶尔很慢,则有如下原因 (1).数据库在刷新脏页,例如 redo log 写满了需要同步到磁盘. (2).执行的时候,遇到锁, ...

  8. 一条SQL语句执行得很慢的原因有哪些?| MySQL高性能优化规范建议

    一条SQL语句执行得很慢的原因有哪些 https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485185&idx=1&am ...

  9. 一条SQL语句执行得很慢的原因有哪些

    说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你"输入URL回车之后,究竟发生了什么"一样,看看你能说出多少了. 之前腾讯 ...

随机推荐

  1. BZOJ2763 [JLOI2011]飞行路线(SPFA + DP)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=2763 Description Alice和Bob现在要乘飞机旅行,他们选择了一家 ...

  2. php与数据库代码开发规范

    php与数据库代码开发规范 1/25/2016 6:00:31 PM php对各类变量命名规范 目录名 文件命名 局部变量命名 使用英文动词名词,用下划线作为单词的分割,所有字母均使用小写 目录 up ...

  3. 还原后缀名为.bak的数据库备份文件

    1.打开SQL Server Management Studio,随便右击击一个数据库选择任务-->还原-->数据库 4.在弹出来的窗口中的源选项中选择设备-->点选择设备--> ...

  4. asp.net,cookie,写cookie,取cookie

    Cookie是一段文本信息,在客户端存储 Cookie 是 ASP.NET 的会话状态将请求与会话关联的方法之一.Cookie 也可以直接用于在请求之间保持数据,但数据随后将存储在客户端并随每个请求一 ...

  5. jsonp帮助你知道你关注的他或她喜欢什么歌曲

    利用腾讯提供的QQ音乐API,返回一段对方在QQ音乐收藏的歌曲名称json数据,并对该json做解析,就能知道你的那个他或她喜欢听什么歌曲了,然后你就知道他/她的品位了,然后就自己看着办了,嘿嘿.我只 ...

  6. 懒加载lazyload

    什么是懒加载 懒加载就是当你做滚动到页面某个位置,然后再显示当前位置的图片,这样做可以减少页面请求. 懒加载:主要目的是作为服务器前端的优化,减少请求数或延迟请求数,一些图片非常多的网站中非常有用,在 ...

  7. bootstrap之排版类

    bootstrap之排版类

  8. SQL 提高查询效率

    1.关于SQL查询效率,100w数据,查询只要1秒,与您分享: 机器情况p4: 2.4内存: 1 Gos: windows 2003数据库: ms sql server 2000目的: 查询性能测试, ...

  9. ajax教程

    本文来自w3school 简介: AJAX = Asynchronous JavaScript and XML 异步的javascript和xml ajax不是新的编程语言,而是一种使用现有标准的新方 ...

  10. Tree菜单 复选框选中控制DEMO

    java 对应实体类属定义 public class AccoSysmanResource{        /**     * 资源类型     */    private Integer resou ...