慢查询中的不同参数值结果

时间:2010-06-16 19:18:27

标签: sql sql-server sql-server-2008 sql-execution-plan

我在SQL Server 2008中有一个sproc。它基本上构建一个字符串,然后使用EXEC()运行查询:

SELECT * FROM [dbo].[StaffRequestExtInfo] WITH(nolock,readuncommitted)
WHERE [NoteDt] < @EndDt 
AND [NoteTypeCode] = @RequestTypeO 
AND ([FNoteDt] >= @StartDt AND [FNoteDt] <= @EndDt) 
AND [FStaffID] = @StaffID 
AND [FNoteTypeCode]<>@RequestTypeC 
ORDER BY [LocName] ASC,[NoteID] ASC,[CNoteDt] ASC

除了@RequestTypeO和@RequestTypeF之外的所有内容都作为sproc参数传入。另外两个是从参数构建到局部变量。通常,查询运行不到一秒钟。但是,对于@StaffID的一个特定值,执行计划是不同的,大约慢30倍。在任何一种情况下,返回的数据量通常都是相同的,但执行时间会逐渐增加。

我试图重新编译sproc。我还尝试将@StaffID“复制”到本地@LocalStaffID中。这两种方法都没有任何区别。

有什么想法吗?

更新:尝试使用以下方式删除特定计划:

DECLARE @ph VARBINARY(64), @pt VARCHAR(128), @sql VARCHAR(1024)

DECLARE cur CURSOR FAST_FORWARD FOR
  SELECT p.plan_handle
  FROM sys.[dm_exec_cached_plans] p
  CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) t
  WHERE t.text LIKE N'%cms_selectStaffRequests%'

OPEN cur
FETCH NEXT FROM cur INTO @ph

WHILE @@FETCH_STATUS = 0
BEGIN
  SELECT @pt = master.dbo.fn_varbintohexstr(@ph)
  PRINT 'DBCC FREEPROCCACHE(' + @pt + ')'
  SET @sql = 'DBCC FREEPROCCACHE(' + @pt + ')'
  EXEC(@sql)
  FETCH NEXT FROM cur INTO @ph
END

CLOSE cur
DEALLOCATE cur

错误的计划被删除,或者同样的计划最终被重建,但它没有效果。

2 个答案:

答案 0 :(得分:0)

检查列FStaffID中值的分布/频率/基数,并检查索引。可能有一个工作人员做了50%的工作(可能是DBA :),这可能会改变优化器选择使用哪些索引以及如何读取数据的方式。

或者,动态代码生成的执行计划可能正在保存和重新使用,导致执行效果不佳(如HLGEM所说)。我不了解细节,但SQL 2008有更多的方法让你在做这件事时比你的前辈迷惑。

答案 1 :(得分:0)

在查询的主基表上执行UPDATE STATISTICS ... WITH FULLSCAN会导致“慢”值与慢速计划无关。