存储过程;插入慢度

时间:2020-03-06 14:35:55  来源:igfitidea点击:

我有一个SP,它需要10秒钟才能运行大约10次(每次运行大约一秒钟)。平台是asp .net,服务器是SQL Server2005. 我已经为表建立了索引(也没有在PK上建立索引),所以这不是问题。一些警告:

  • usp_SaveKeyword不是问题。我评论说整个SP并没有什么区别。
  • 我将@SearchID设置为1,时间大大减少了,事务平均只需要15毫秒。
  • 我注释掉了整个存储过程,除了插入到tblSearches中之外,奇怪的是执行起来花了更多时间。

关于会发生什么的任何想法?

set ANSI_NULLS ON

go

ALTER PROCEDURE [dbo].[usp_NewSearch]

  @Keyword VARCHAR(50),

  @SessionID UNIQUEIDENTIFIER,

  @time SMALLDATETIME = NULL,

  @CityID INT = NULL

AS

BEGIN

  SET NOCOUNT ON;

  IF @time IS NULL SET @time = GETDATE();

  DECLARE @KeywordID INT;

  EXEC @KeywordID = usp_SaveKeyword @Keyword;

  PRINT 'KeywordID : '

  PRINT @KeywordID

  DECLARE @SearchID BIGINT;     

  SELECT TOP 1 @SearchID = SearchID

    FROM tblSearches 

   WHERE SessionID = @SessionID

     AND KeywordID = @KeywordID;

  IF @SearchID IS NULL BEGIN

        INSERT INTO tblSearches

              (KeywordID, [time], SessionID, CityID)

         VALUES

              (@KeywordID, @time, @SessionID, @CityID)

        SELECT Scope_Identity();

  END

  ELSE BEGIN

        SELECT @SearchID

  END

END

解决方案

扳机!

他们确实是阴险的。

在SQL Management Studio中启用"显示估计的执行计划",执行计划在哪里显示我们花费的时间?它将引导我们了解用于优化查询的启发式方法(或者在本例中不是)。通常," fatter"行是要重点关注的行,它们是生成大量I / O的行。

不幸的是,即使我们告诉我们表模式,也只有我们才能看到SQL实际选择如何优化查询。最后一件事,我们是否在tblSearches上获得了聚集索引?

为什么在此查询中使用"前1个@SearchID"而不是" max(SearchID)"或者" where where"? " top"要求我们运行查询并从结果集中检索第一行。如果结果集很大,那么在得出最终结果集之前可能会消耗大量资源。

SELECT TOP 1 @SearchID = SearchID    
  FROM tblSearches    
 WHERE SessionID = @SessionID     
   AND KeywordID = @KeywordID;

我看不出有任何明显的原因使上述任何一种构造都可以通过非常便宜的索引查找在语义上等效于我们。除非我缺少任何东西,否则我们应该可以做类似的事情

select @SearchID = isnull (max (SearchID), -1)
  from tblSearches
 where SessionID = @SessionID
   and KeywordID = @KeywordID

这应该是相当有效的,并且(除非我遗漏了一些东西)在语义上是等效的。

  • 什么是tblSearches上的聚集索引?如果聚簇索引不在主键上,则数据库可能会花费大量时间进行重新排序。
  • 我们还有多少其他索引?
  • 你有触发器吗?
  • 执行计划在哪里指示正在花费时间?