| 技術 | 作用 |
SELECT DISTINCT n1,n2,n3 | 依組合鍵去重,保留唯一業務記錄 |
CROSS JOIN (SELECT @row := 0) | 初始化用戶變數 @row = 0,產生單行虛表參與 JOIN |
@row := @row + 1 | 每行遞增 1,生成連續整數序列作為新主鍵 |
| 列順序對應 | id, n1, n2, n3 嚴格對應 SELECT 列順序 |
進階變體:指定排序後再編號
INSERT INTO A (id, n1, n2, n3)
SELECT @row := @row + 1, t1.n1, t1.n2, t1.n3
FROM (
SELECT DISTINCT n1, n2, n3 FROM B ORDER BY n1, n2
) t1
CROSS JOIN (SELECT @row := 0) t2;
MySQL 8.0+ 現代寫法 (CTE + ROW_NUMBER)
WITH dedup AS (
SELECT DISTINCT n1, n2, n3 FROM B
),
numbered AS (
SELECT ROW_NUMBER() OVER (ORDER BY n1, n2) AS id, n1, n2, n3 FROM dedup
)
INSERT INTO A (id, n1, n2, n3)
SELECT id, n1, n2, n3 FROM numbered;
優勢:標準 SQL、可讀性高、支援複雜排序/分組編號、無用戶變數副作用。
大表效能優化建議
- 舊表
(n1,n2,n3) 建立**複合索引**加速 DISTINCT 掃描
- 分批遷移:
WHERE n1 BETWEEN ... 分範圍執行多條 SQL
- 關閉 Binlog (會話級) 減少主從延遲:
SET SESSION sql_log_bin = 0;
- 使用
LOAD DATA 先導出 CSV 再匯入 (最快)
驗證腳本
-- 行數一致性
SELECT COUNT(*) FROM A;
SELECT COUNT(DISTINCT n1,n2,n3) FROM B;
-- 主鍵連續性
SELECT MAX(id) - COUNT(*) + 1 AS gap_count FROM A; -- 應為 1
-- 業務鍵唯一性
SELECT n1,n2,n3, COUNT(*) FROM A GROUP BY n1,n2,n3 HAVING COUNT(*) > 1;
- 上一篇文章: MySQL InnoDB 插入意向鎖機制深度解析:為何需要、如何避免幻讀與並發衝突
- 下一篇文章: SQL 注入之基於錯誤回顯攻擊完整手冊:原理、Payload 與實戰演練
Copyright ©
程式碼之家 All Rights Reserved