代码之家  ›  专栏  ›  技术社区  ›  alphadogg

不同的参数值导致查询缓慢

  •  0
  • alphadogg  · 技术社区  · 14 年前

    我在SQL Server 2008中有一个存储过程。它基本上构建一个字符串,然后使用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之外,其余的都作为存储过程参数传入。另外两个是从参数构建成局部变量的。通常,查询在一秒钟内运行。但是,对于@staffid的一个特定值,执行计划是不同的,大约慢了30倍。在这两种情况下,返回的数据量通常都是相同的,但执行时间会增加。

    我试图重新编译存储过程。我还试图将@staffid“复制”到本地的@local staffid中。两种方法都没有任何区别。

    有什么想法吗?

    更新:尝试删除特定计划时使用:

    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 回复  |  直到 12 年前
        1
  •  0
  •   Philip Kelley    14 年前

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

    或者,动态代码生成的执行计划可能会被保存并重新使用,从而导致查询性能不佳(如hlgem所说)。我不了解细节,但在做这件事时,SQL 2008有比它的前辈更多的方法来迷惑您。

        2
  •  0
  •   alphadogg    14 年前

    做一个 UPDATE STATISTICS ... WITH FULLSCAN 在查询的主基表上,导致“slow”值未与慢计划关联。