sql-server - 使用参数时查询很慢,但使用文字时查询很快

标签 sql-server azure-sql-database parameter-sniffing

我有一个针对相当大的表运行的查询,我需要对其进行计数。

如果我使用文字,查询会在几秒钟内运行,但是当我将值作为变量放入时(我需要这样做),查询将永远持续下去,并且可能会进行全表扫描。

我已经阅读了大量有关此内容的文章,并且我理解它最有可能与参数嗅探有关,我不能假装我理解它,我只是想知道如何修复它,否则,我将不得不依靠生成的查询字符串在 C# 中调用它。

此查询将在几秒钟内运行..

  SELECT Count(Id) FROM  dbo.BeaconScan WHERE State = 'Archived' AND  LastSeen < '29 February 2020';

这需要永远

DECLARE @Date DATE = '31 March 2020'
DECLARE @Status NVARCHAR(256) = 'Archived'
SELECT Count(Id) FROM  dbo.BeaconScan WHERE State = @Status AND  LastSeen < @Date;

最佳答案

SQL Server 根据行计数估计和启发式优化查询。这些估计可能因文字、局部变量或参数而异。

使用文字或参数(在应用程序代码中声明并随命令传递的参数),SQL Server 根据提供的实际值和统计直方图(如果列上存在索引或统计信息)估计计数。当统计数据是最新的时,这通常会产生准确的估计和最佳计划。

使用局部变量(T-SQL DECLARE 语句)或 OPTIMIZE FOR UNKNOWN 查询提示,SQL Server 根据值的总体平均密度估计计数并忽略实际值和直方图。这通常会产生一个折衷计划,该计划总体上可能足够好,但对于某些值可能不是最佳的。向具有局部变量的查询添加OPTION (RECOMPILE)查询提示将使用实际的局部变量值进行优化,并产生与指定文字相同的计划。

请注意,没有 RECOMPILE 提示的参数化查询计划将被缓存和重用。重用计划时将忽略当前参数值,因此重用的查询计划对于当前参数值可能不是最佳的。这是OPTION (RECOMPILE) 可能提高性能的另一种情况。

考虑查询执行频率,明智地使用OPTION (RECOMPILE)提示。编译开销可能超过频繁执行的查询(例如每秒多次)节省的运行时时间。

关于sql-server - 使用参数时查询很慢,但使用文字时查询很快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64712644/

相关文章:

sql-server - sql server 全文搜索 - 在全文搜索中查找同义词库的示例用法

sql-server - 插入动态 WHERE 条件

azure - Powershell - 使用 Connect-AzAccount(使用 MFA)连接到 SQL Server

sql - 在您 SQL Server 职业生涯的某个阶段,参数嗅探是否会突然跳出来并发起攻击?

sql - 更新一个变量的动态sql语句

sql-server - 如何对 SQL SERVER 中的一组记录应用过滤器

Azure 数据从 Azure Db 同步到 Azure DWH

sql - 流利的 NHibernate : How to create a clustered index on a Many-to-Many Join Table?

sql-server - 您是否应该总是预见到参数嗅探引起的问题?