Sql server 在SQL Server中,当SELECT子句中的变量

Sql server 在SQL Server中,当SELECT子句中的变量,sql-server,performance,variables,select,Sql Server,Performance,Variables,Select,我在SQL Server Management Studio中运行了以下简单代码: DECLARE @CurDeviceIndex int SET @CurDeviceIndex = 314 SELECT TOP 1 DeviceIndex, DatetimeOccurred FROM [dvm_data].[dbo].[CalculatedData] WHERE DeviceIndex = @CurDeviceIndex ORDER BY

我在SQL Server Management Studio中运行了以下简单代码:

DECLARE @CurDeviceIndex  int
SET @CurDeviceIndex = 314

SELECT TOP 1 
    DeviceIndex, 
    DatetimeOccurred 
FROM 
    [dvm_data].[dbo].[CalculatedData] 
WHERE 
    DeviceIndex = @CurDeviceIndex 
ORDER BY 
    ID DESC
在某些情况下,这个查询需要花费很长时间才能运行,实际上我从来没有等到结束。 当我将DeviceIndex直接放入查询而不是变量时,它会立即执行:

SELECT TOP 1 
    DeviceIndex, 
    DatetimeOccurred 
FROM 
    [dvm_data].[dbo].[CalculatedData] 
WHERE 
    DeviceIndex = 314 
ORDER BY 
    ID DESC
当使用1个变量时,执行似乎要花费很长时间,而DeviceIndex是这样的:查询什么也不返回。 当查询返回某个内容时,那个么带有变量的版本似乎也立即起作用

当我使用硬编码的DeviceIndex时,无论是否有结果,每次查询都会立即返回


知道是什么导致了这种奇怪的行为吗

由于您在management studio中使用变量,因此SQL Server在您运行它时不知道它的值,必须针对未知值优化计划

如果在过程中使用相同的子句,它将知道该值并对其进行优化-但这发生在第一次调用时,其余执行将使用相同的计划,除非发生重新编译或计划被抛出缓存

当您直接在SQL中使用该值时,语句将针对该确切值进行优化


如果您想知道为什么需要更长的时间,您必须查看查询计划。很可能其中一个计划中有扫描,另一个计划中有搜索。您可以从计划中最左侧对象的属性中查看用于创建计划的参数值。

听起来像是错误的参数嗅探。这是一篇关于这个主题的优秀文章。确保你也阅读了第2部分和第3部分。如果你想潜得更深一点,那就做吧。