sql-server - SQL Server 中的参数嗅探(或欺骗)

标签 sql-server tsql sql-server-2005 parameter-spoofing

不久前,我有一个查询,我为我的一个用户运行了很多次。它仍在不断发展和调整,但最终它稳定下来并且运行得相当快,因此我们从中创建了一个存储过程。

到目前为止,一切都很正常。

但是,存储过程非常慢。查询和过程之间没有实质性差异,但速度变化很大。

[背景,我们正在运行 SQL Server 2005。]

一位友好的本地 DBA(他不再在这里工作)看了一眼存储过程并说“参数欺骗!” (编辑:虽然它似乎也可能被称为“参数嗅探”,这可能解释了当我试图搜索它时 Google 的点击量很少。)

我们将一些存储过程抽象为第二个存储过程,将对这个新内部过程的调用包装到预先存在的外部过程中,称为外部过程,嘿,很快,它和原始查询一样快。

那么,什么给出了呢?有人可以解释一下参数欺骗吗?

奖励积分

  • 强调如何避免这种情况
  • 建议如何识别可能的原因
  • 讨论替代策略,例如统计数据、索引、键,用于缓解这种情况

最佳答案

仅供引用 - 当您使用 SQL 2005 和带参数的存储过程时,您需要注意其他事项。

SQL Server 将使用使用的第一个参数编译存储过程的执行计划。所以如果你运行这个:

usp_QueryMyDataByState 'Rhode Island'

执行计划最适合小状态的数据。但如果有人转身就跑:

usp_QueryMyDataByState 'Texas'

为罗德岛州规模的数据设计的执行计划对于德克萨斯州规模的数据可能效率不高。当服务器重新启动时,这可能会产生令人惊讶的结果,因为新生成的执行计划将针对首先使用的任何参数 - 不一定是最好的参数。除非有重大原因,例如重建统计数据,否则该计划不会重新编译。

这就是查询计划的用武之地,SQL Server 2008 提供了许多新功能,可以帮助 DBA 长期固定特定的查询计划,无论首先调用什么参数。

我担心的是,当您重建存储过程时,您强制执行计划重新编译。你用你最喜欢的参数调用它,然后当然它很快 - 但问题可能不是存储过程。存储过程可能在某个时刻使用一组不寻常的参数重新编译,因此查询计划效率低下。您可能没有修复任何内容,并且下次服务器重新启动或重新编译查询计划时您可能会遇到相同的问题。

关于sql-server - SQL Server 中的参数嗅探(或欺骗),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/211355/

相关文章:

sql - 列名称或提供的值的数量与表定义不匹配

sql-server - t-sql 查询连接相应的行

sql - 存储过程中是否需要 "SET NOCOUNT OFF"?

sql-server - 将 CSV 导入 SQl Server 2005 的最简单方法

vb.net - 我的用户可以注入(inject)我的动态 sql 吗?

sql-server - 如何根据特殊字符串在列中的位置获取值

sql-server - SQL Server Management Studio 在编辑行时崩溃

sql - 用于报告和日常交易的数据库

sql-server - 查找/控制非法数据的方法

sql-server-2005 - 在 SQL Server 2005 中将多列作为单个逗号分隔的行返回