通过C#

时间:2018-01-31 07:04:25

标签: sql-server tsql stored-procedures

我有一个拥有250万条记录的SQL Server数据库,我需要更新记录。源是一个使用存储过程的C#程序。检查后,存储过程需要很长时间才能更新。

当我使用交易时,1000条记录大约需要10分钟。我已经将索引键放在用于搜索的所有列上,或者如果列上有条件,这无助于加速。

唯一标识符是字符串,不能更改为数字值。其他列的值是可更改的。我认为我的减速原因在下一节

FROM 
    [Policy] 
WHERE
    [UniqueIdentifier] = @UniqueIdentifier
    AND ([ParentIdentifierId] != @ParentIdentifierId
         OR [PolId] != @PolId
         OR [ClaimNumber] != @ClaimNumber
         OR [ClaimStatus] != @ClaimStatus
         OR [Description] != @Description))

我已经删除了只进行更新但没有任何其他功能的列的存储过程。列总数为30。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[sp_WriteDatatoolUpdate_test01] 
    @Dossier VARCHAR(50),
    @ParentIdentifierId VARCHAR(50),
    @PolId VARCHAR(50),
    @ClaimNumber VARCHAR(50),
    @ClaimStatus VARCHAR(50),
    @Description VARCHAR(255),
    @RecordExtractionDate VARCHAR(50),
    @UniqueIdentifier VARCHAR(50),
    @RecordCreationDate DATE = NULL,
    @UpDate DATE = NULL,
    @ChangedAfterUpdate VARCHAR(1),
AS
BEGIN
    IF NOT EXISTS(SELECT 1 FROM [Policy] 
                  WHERE [UniqueIdentifier] = @UniqueIdentifier)
    BEGIN
        INSERT INTO [Policy] ([Dossier], [ParentIdentifierId], [PolId],
                              [ClaimNumber], [ClaimStatus], [Description],
                              [RecordExtractionDate], [UniqueIdentifier], 
                              [RecordCreationDate],[UpDate],[ChangedAfterUpdate]
        VALUES (@Dossier, @ParentIdentifierId, @PolId,
                @ClaimNumber, @ClaimStatus, @Description,
                @RecordExtractionDate, @UniqueIdentifier,
                @RecordCreationDate, @UpDate, @ChangedAfterUpdate 
    END
    ELSE
    BEGIN
        IF EXISTS(SELECT 1 
                  -- probable cause of the slowdown
                  -- Need to select1 and check if needed to update
                  FROM [Policy] 
                  WHERE [UniqueIdentifier] = @UniqueIdentifier
                    AND ([ParentIdentifierId] != @ParentIdentifierId
                         OR [PolId] != @PolId
                         OR [ClaimNumber] != @ClaimNumber
                         OR [ClaimStatus] != @ClaimStatus
                         OR [Description] != @Description))
                -- here are some more fields to check,
        BEGIN
            UPDATE [Policy] 
            SET [ParentIdentifierId] = @ParentIdentifierId,
                [PolId] = @PolId,
                [ClaimNumber] = @ClaimNumber,
                [ClaimStatus] = @ClaimStatus,
                [Description] = @Description,
                [UpDate] = CONVERT(DATE, GETDATE()),
                [ChangedAfterUpdate ] = 'Y'
            WHERE [UniqueIdentifier] = @UniqueIdentifier
        END
        ELSE
        BEGIN
            UPDATE [Policy] 
            SET [UpDate] = CONVERT(date,GETDATE()),
                [ChangedAfterUpdate ] = 'N'
            WHERE [UniqueIdentifier] = @UniqueIdentifier
        END
    END
END

1 个答案:

答案 0 :(得分:0)

更新中的列数量(10 vs 30)对性能没有显着影响。在您的情况下,问题可能是您怀疑的情况。以下是一些尝试的策略:

隔离慢查询 使用Sql Server工具隔离查询的慢速部分:Query plan visualizer和/或SQL profiler。在你的情况下,慢速部分可以是查询的包含多个OR条件的where子句。

优化慢查询 通过修改索引来优化慢速查询和/或在可能的情况下将其重构为单独的子查询。

尽可能使用批量操作 如果可能,使用批量操作并避免大量的逐个sql事务。如果使用.NET BulkCopy insertions,则可能需要一些额外的临时表和合并操作。可以使用以下工具实现批量更新: