首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL Server 刪除重複資料高效能技法:四步驟避開游標陷阱

     編輯:MySQL 資料庫相關知識

痛點:游標刪除百萬筆資料 = 效能災難

傳統寫法用游標逐列比對刪除,複雜度 O(n²),百萬筆資料需跑數小時。實際上只要一條 INSERT 搭配忽略重複值的索引 即可秒級完成。

四板斧實戰步驟

第一板斧:建立相同結構的暫存表

CREATE TABLE Products_temp (
    ProductID int,
    ProductName nvarchar(40),
    Unit char(2),
    UnitPrice money
);

第二板斧:加上「忽略重複值」的唯一索引

企業管理器 → 該表 → 右鍵「所有工作」→「管理索引」→「新增」→ 勾選 「忽略重複值」(IGNORE_DUP_KEY = ON),索引鍵設為業務主鍵(如 ProductName 或組合鍵)。

等效 T-SQL:

CREATE UNIQUE INDEX IX_Products_temp_Name
ON Products_temp (ProductName)
WITH IGNORE_DUP_KEY = ON;

第三板斧:將資料導入暫存表

INSERT INTO Products_temp (ProductID, ProductName, Unit, UnitPrice)
SELECT ProductID, ProductName, Unit, UnitPrice
FROM Products;

重複鍵的列會被自動忽略,只保留第一筆,無錯誤訊息。

第四板斧:替換原表

DROP TABLE Products;
EXEC sp_rename 'Products_temp', 'Products';
-- 重建原有索引、外鍵、觸發器、權限

進階:保留特定重複列(如最新/最舊)

若需保留每組重複中的特定列(如 MAX(ProductID)),改用 ROW_NUMBER() 分組排序:

WITH CTE AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY ProductName ORDER BY ProductID DESC) AS rn
    FROM Products
)
DELETE FROM Products
WHERE ProductID IN (
    SELECT ProductID FROM CTE WHERE rn > 1
);

適用 SQL Server 2005+,單一陳述式、無游標、效能極佳。

MySQL 對應做法

-- 建立唯一索引忽略重複(MySQL 不支援 IGNORE_DUP_KEY,改用 INSERT IGNORE)
CREATE TABLE Products_temp LIKE Products;
ALTER TABLE Products_temp ADD UNIQUE KEY ux_name (ProductName);

INSERT IGNORE INTO Products_temp SELECT * FROM Products;

RENAME TABLE Products TO Products_old, Products_temp TO Products;

總結

善用唯一索引 + IGNORE_DUP_KEY / INSERT IGNORE 或 窗口函數 ROW_NUMBER(),將刪除重複資料從「游標地獄」解脫為「單一 SQL 秒殺」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved