表 tblMulCharge 以 orderno 為去重鍵,需保留首筆記錄刪除其餘重複列。資料量大時,方法選擇直接影響執行時間與鎖定爭用。
SELECT * FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY orderno ORDER BY (SELECT 0)) AS RowNO, *
FROM tblMulCharge
) t
WHERE t.RowNO > 1;
缺點:僅能查詢重複列,無法直接刪除;需搭配 JOIN 或 IN 子句才能刪除,效能較差。
WITH ct01 AS (
SELECT ROW_NUMBER() OVER (PARTITION BY orderno ORDER BY (SELECT 0)) AS rn
FROM tblMulCharge
)
DELETE FROM ct01 WHERE rn > 1;
優點:語法簡潔、單陳述式完成。
缺點:大資料量時交易記錄膨脹、鎖定升級風險高,可能導致記錄檔暴增。
WITH ct01 AS (
SELECT
[ID], [OriOrderNo], [OrderNo], [TotalAmount], [PayAmount],
[ProviderAmount], [transaction_id], [PNRCode], [Consumer],
[Provider], [SellerAccount], [BuyerAccount], [State], [PayTime],
[PayInfo], [RefundTime], [refund_id], [refund_info],
[RefundTimeV], [refund_id_V], [refund_info_V], [RefundAmount],
ROW_NUMBER() OVER (PARTITION BY orderno ORDER BY (SELECT 0)) AS rn
FROM tblMulCharge
)
SELECT
[ID], [OriOrderNo], [OrderNo], [TotalAmount], [PayAmount],
[ProviderAmount], [transaction_id], [PNRCode], [Consumer],
[Provider], [SellerAccount], [BuyerAccount], [State], [PayTime],
[PayInfo], [RefundTime], [refund_id], [refund_info],
[RefundTimeV], [refund_id_V], [refund_info_V], [RefundAmount]
INTO dbo.tblMulCharge_tmp
FROM ct01
WHERE rn = 1;
DROP TABLE dbo.tblMulCharge;
EXEC sp_rename 'dbo.tblMulCharge_tmp', 'tblMulCharge';
| 維度 | 方法二 (DELETE) | 方法三 (重建表) |
|---|---|---|
| 交易記錄體積 | 逐列記錄,極大 | 最小化記錄 (最小日誌模式下) |
| 鎖定範圍 | 逐列/頁/表鎖升級 | Schema 修改鎖,時間極短 |
| 索引重建 | 需額外 REBUILD | 同步建立,無碎片 |
| 可中斷性 | 難以中斷回滾 | 分步驟,可控風險 |