SQL Server 游标性能问题

问题描述 投票:0回答:1

需要您帮助优化光标或完全更改代码。 我有以下要求:

创建按 ColumnA、ColumnD 和 GroupA 分组的列 Sequence。 StartA用于排序。尝试使用 LAG、Row_Number 等,但没有任何乐趣,因为考虑到 ColumnA(可以重复)和按 StartA 排序的 GroupA,分组序列在更改 Column D 时重新启动。

下面的代码对于一小部分记录来说工作得很好,但是上次我运行它花了 3 个多小时并且没有完成,所以我已经终止了这项工作。该表有超过 700,000 条记录。寻找有关如何改进这一点的任何提示。谢谢!

DECLARE 
        @ColumnA VARCHAR(10),
        @StartA DATETIME,
        @ColumnD VARCHAR(50),
        @Sequence INTEGER,
        @Sequence_Calc INTEGER = 1,
        @Previous_ColumnA VARCHAR(10),
        @Previous_ColumnD VARCHAR(50)

    

SELECT *
    INTO #Temp_Table
    FROM TABLEA
    ORDER BY ColumnA,
        ColumnD


DECLARE Seq_Cursor CURSOR 

    FOR SELECT  ColumnA,
             StartA,
             ColumnD,
             Sequence
      FROM #Temp_Table
    ORDER BY ColumnA,
        ColumnD

FOR UPDATE OF Sequence

OPEN Seq_Cursor

    FETCH NEXT FROM Seq_Cursor
        INTO    @ColumnA, @StartA, @ColumnD, @Sequence 


WHILE @@FETCH_STATUS= 0

BEGIN

    BEGIN
        UPDATE #Temp_Table
        SET Sequence = @Sequence_Calc
        WHERE ColumnD = @ColumnD
        AND StartA = @StartA
        AND ColumnA = @ColumnA

        SET @Previous_ColumnA = @ColumnA
        SET @Previous_ColumnD = @ColumnD
    
    END

        FETCH NEXT FROM Seq_Cursor
        INTO     @ColumnA, @StartA, @ColumnD, @Sequence
    
    BEGIN 
         SELECT @Sequence_Calc = CASE WHEN @Previous_ColumnD = @ColumnD THEN 
                                 CASE WHEN @Previous_ColumnA <> @ColumnA THEN @Sequence_Calc + 1 ELSE @Sequence_Calc END 
                                 ELSE 1 END 
    END

END
CLOSE Seq_Cursor
DEALLOCATE Seq_Cursor
sql-server performance cursor
1个回答
0
投票

不知道为什么你要摆弄游标,它们速度慢且效率低,编写起来复杂,理解起来也很复杂。

看起来你只需要

DENSE_RANK

SELECT *,
  DENSE_RANK() OVER (PARTITION BY ColumnD ORDER BY GroupA, ColumnA)
FROM TABLEA a

PARTITION BY
重置该列每个值的编号。
DENSE_RANK
为您提供相同排序的并列结果。

© www.soinside.com 2019 - 2024. All rights reserved.