我有一个拥有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
答案 0 :(得分:0)
更新中的列数量(10 vs 30)对性能没有显着影响。在您的情况下,问题可能是您怀疑的情况。以下是一些尝试的策略:
隔离慢查询 使用Sql Server工具隔离查询的慢速部分:Query plan visualizer和/或SQL profiler。在你的情况下,慢速部分可以是查询的包含多个OR条件的where子句。
优化慢查询 通过修改索引来优化慢速查询和/或在可能的情况下将其重构为单独的子查询。
尽可能使用批量操作 如果可能,使用批量操作并避免大量的逐个sql事务。如果使用.NET BulkCopy insertions,则可能需要一些额外的临时表和合并操作。可以使用以下工具实现批量更新: