Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 如何使函数在SQL中执行得更快?_Sql Server 2008_Function_Database Performance - Fatal编程技术网

Sql server 2008 如何使函数在SQL中执行得更快?

Sql server 2008 如何使函数在SQL中执行得更快?,sql-server-2008,function,database-performance,Sql Server 2008,Function,Database Performance,我正在使用函数更新到一列,如 DetailedStatus = dbo.fn_GetProcessStageWiseStatus(PR.ProcessID, PR.ProcessRunID, getdate()) 在这一行中,500000条记录不断更新。就像一个环 因此,对少数记录使用此函数时,它的执行速度很快,但当它的500000条记录执行时,它会变得非常慢 如何使用多个记录使其执行更快 需要采取什么措施或使用什么拆分 功能: 结束 提前感谢。当您尝试更新500k行时,执行计划似乎有所更改

我正在使用函数更新到一列,如

DetailedStatus = dbo.fn_GetProcessStageWiseStatus(PR.ProcessID, PR.ProcessRunID, getdate()) 
在这一行中,500000条记录不断更新。就像一个环

因此,对少数记录使用此函数时,它的执行速度很快,但当它的500000条记录执行时,它会变得非常慢

如何使用多个记录使其执行更快

需要采取什么措施或使用什么拆分

功能:

结束


提前感谢。

当您尝试更新500k行时,执行计划似乎有所更改。 您可以尝试在from子句上设置forceseek提示,以强制使用seeks而不是scans

另外,虽然@iRowCount>@IlopCount应该替换为if exists,因为您基本上是在结果表上检查某些条件,并且需要尽早返回

我看到您在任何地方都使用nolock hint来允许脏读,您可以在调用存储过程中设置隔离级别read uncommitted并删除所有这些;或者考虑更改数据库以设置Read TypReType快照以避免锁。


顺便说一句,SQL Server中的标量函数调用非常昂贵,因此,如果在调用函数的循环中发生了大量更新/选择,则必须尽量避免使用函数。

向我们展示该函数的功能!给我们看看代码!你能检查编辑过的问题而不是函数吗?你建议使用什么样的函数?@Pink将所有代码都放在一个存储过程中;是的,这违反了干吻原则。从基于集合的操作的角度重新思考所有代码,目前您正在以行为单位逐段执行所有操作。
             CREATE FUNCTION [dbo].[fn_GetProcessStageWiseStatus]    
       (    
       @ProcessID INT    
        ,@ProcessRunID INT    
        ,@SearchDate SMALLDATETIME    
       )    
          RETURNS VARCHAR(100)    
         AS    

      BEGIN    
         DECLARE      
             @iLoopCount SMALLINT    
            ,@iRowCount SMALLINT    
            ,@StepProgress VARCHAR(100)    
            ,@StepCount SMALLINT    

     IF EXISTS(    
              SELECT TOP 1 1    
              FROM dbo.Step S WITH(NOLOCK)    
              JOIN dbo.vw_FileGroup FG    
                    ON S.FileConfigGroupID = FG.FileConfigGroupID    
              WHERE S.ProcessID = @ProcessID    
              AND S.Active = 1    
              AND FG.FileConfigGroupActive = 1    
              AND FG.Direction = 'Inbound'    
              )    
  BEGIN    
        SET @StepProgress = 'Not Received'    
  END    
  ELSE    
  BEGIN    
        SET @StepProgress = 'Not Started'    
  END    

  DECLARE @StepRunDetailsTable TABLE    
  (    
        KeyNo INT IDENTITY(1,1)    
        ,StepID INT    
        ,StepStartTime SMALLDATETIME    
        ,StepEndTime SMALLDATETIME    
        ,SourceEnv VARCHAR(100)    
        ,DestEnv VARCHAR(100)    
  )    

  INSERT INTO @StepRunDetailsTable     
  SELECT    
        S.StepID    
        ,MAX(isnull(SR.StepStartTime, '06/06/2079'))    
        ,MAX(isnull(SR.StepEndTime, '06/06/2079'))    
        ,isnull(SENV.EnvironmentName, '')    
        ,isnull(DENV.EnvironmentName, '')    
  FROM dbo.ProcessRun PR WITH(NOLOCK)    
  JOIN dbo.StepRun SR WITH(NOLOCK)    
        ON SR.ProcessRunID = PR.ProcessRunID    
  JOIN dbo.vw_StepHierarchy SH    
        ON SR.StepID = SH.StepID    
        AND SH.Active = 1    
  JOIN dbo.Step S WITH(NOLOCK)    
        ON SH.StepID = S.StepID    
  JOIN dbo.WorkFlow WF WITH(NOLOCK)    
        ON S.WorkFlowID = WF.WorkFlowID    
        AND WF.Active = 1           
  JOIN dbo.Environment SENV WITH(NOLOCK)    
        ON SENV.EnvironmentID = WF.SourceEnvironmentID    
        AND SENV.Active = 1               
  JOIN dbo.Environment DENV WITH(NOLOCK)    
        ON DENV.EnvironmentID = WF.DestinationEnvironmentID    
        AND DENV.Active = 1    
  WHERE PR.ProcessRunID = @ProcessRunID    
  GROUP BY S.StepID, SENV.EnvironmentName, DENV.EnvironmentName, SH.StepOrder    
  ORDER BY SH.StepOrder ASC    

  SELECT @StepCount = COUNT(*)    
  FROM dbo.ProcessRun PR WITH(NOLOCK)    
  JOIN dbo.Step S WITH(NOLOCK)    
        ON PR.ProcessID = S.ProcessID    
        AND PR.ProcessRunID = @ProcessRunID    
        AND S.Active = 1    

  SELECT @iRowCount = COUNT(DISTINCT StepID) FROM @StepRunDetailsTable    

  SET @iLoopCount = 0      

  WHILE (@iRowCount > @iLoopCount)      
  BEGIN      
        SET @iLoopCount = @iLoopCount + 1    

        SELECT    
              @StepProgress =     
                    CASE    
                          --WHEN @SearchDate BETWEEN StepStartTime AND StepEndTime     
                          WHEN @SearchDate >= StepStartTime AND  @SearchDate <= StepEndTime     
                                THEN DestEnv + ' Load in Progress'    
                          WHEN @SearchDate > StepEndTime AND @iLoopCount < @StepCount    
                                THEN 'Waiting on next step - Loaded to ' + DestEnv    
                          WHEN @SearchDate > StepEndTime AND @iLoopCount = @StepCount    
                                THEN 'Completed'    
                          WHEN @SearchDate < StepStartTime AND @iLoopCount = 1    
                                THEN 'Load Not Started'    
                          ELSE @StepProgress    
              END    

        FROM @StepRunDetailsTable    
        WHERE KeyNo = @iLoopCount    
  END    

  RETURN @StepProgress