You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSMS中高效查找并删除ServiceCodes表重复组合行方案求助

高效删除ServiceCodes表中重复的新增记录

我有一张ServiceCodes表,包含Customer、companyId、ServiceCode、CompanySourc、NewlyInserted字段。插入记录时,会存在Customer和ServiceCode组合重复的行,这类重复行的NewlyInserted字段会被设为1。现在需要查找并删除这类重复行,之前尝试Inner Join、Cross Apply等方法未成功,原更新删除方案在数据量增大时运行极慢,需要高效解决方案,该删除操作每次用户点击按钮时执行。

示例数据

custID1,compid1,Service1233,CompSource1,0
custID2,compid1,Service1234,CompSource1,0
custID3,compid1,Service1235,CompSource1,0
custID4,compid1,Service1236,CompSource1,0
custID3,compid1,Service1235,CompSource1,1
custID4,compid1,Service1236,CompSource1,1

原低效代码

UPDATE Servicecodes  
            SET isNeedstobeDelete = 1
            FROM Servicecodes
            CROSS APPLY (SELECT distinct Client,ServiceCode FROM Servicecodes WHERE NewlyInserted = 0) AS ApplicableClients
            WHERE
                NewlyInserted = 1
                AND [Servicecodes].Client= [ApplicableClients].Client
                AND NOT EXISTS (SELECT 1 FROM @tempservicecodes 
                WHERE [Servicecodes].servicecode = [ApplicableClients].servicecode 
                AND [Servicecodes].clientid = [ApplicableClients].clientid)

delete from servicecodes where isNeedstobeDelete = 1

高效解决方案

方案1:直接通过EXISTS定位删除

跳过中间更新标记字段的步骤,直接用EXISTS定位符合条件的重复记录并删除,减少IO开销:

DELETE sc
FROM ServiceCodes sc
WHERE sc.NewlyInserted = 1
AND EXISTS (
    SELECT 1
    FROM ServiceCodes sc_exist
    WHERE sc_exist.Customer = sc.Customer
      AND sc_exist.ServiceCode = sc.ServiceCode
      AND sc_exist.NewlyInserted = 0
)

方案2:ROW_NUMBER分组标记删除(适合多重复场景)

如果存在同一Customer+ServiceCode组合下多条重复记录,可通过窗口函数分组标记后删除:

WITH DuplicateCTE AS (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY Customer, ServiceCode 
            ORDER BY NewlyInserted ASC -- 保留NewlyInserted=0的原始记录
        ) AS RowNum
    FROM ServiceCodes
)
DELETE FROM DuplicateCTE
WHERE RowNum > 1 AND NewlyInserted = 1

关键优化建议

  • 创建复合索引:给ServiceCodes表添加索引,大幅提升查询匹配效率:
    CREATE NONCLUSTERED INDEX IX_ServiceCodes_Customer_ServiceCode_NewlyInserted 
    ON ServiceCodes (Customer, ServiceCode, NewlyInserted)
    
  • 分批删除(大数据量场景):避免一次性删除大量数据导致锁表,采用循环分批删除:
    WHILE 1=1
    BEGIN
        DELETE TOP (1000) sc
        FROM ServiceCodes sc
        WHERE sc.NewlyInserted = 1
        AND EXISTS (
            SELECT 1
            FROM ServiceCodes sc_exist
            WHERE sc_exist.Customer = sc.Customer
              AND sc_exist.ServiceCode = sc.ServiceCode
              AND sc_exist.NewlyInserted = 0
        )
        IF @@ROWCOUNT = 0 BREAK
    END
    

内容的提问来源于stack exchange,提问作者Sanjay G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 11:29:52