表 data_content_152 500 萬行,實際唯一身份證號(SFZHM)僅 180 萬,需去重保留首條記錄。
CREATE TABLE tmp3 AS SELECT MIN(id) AS col1 FROM data_content_152 GROUP BY SFZHM;
MIN(id) 確定保留哪一行(業務通常保留最早插入)。GROUP BY SFZHM 產生 180 萬組,極快。CREATE TABLE `res` ( `id` INT(11), `sfz` CHAR(20) ) ENGINE=MyISAM;
用 MyISAM 避免事務開銷,純導入更快;若需事務可用 InnoDB。
INSERT INTO res (sfz) SELECT d.SFZHM FROM data_content_152 d JOIN tmp3 t ON d.id = t.col1;
JOIN 比 IN/EXISTS 效率高得多(MySQL 對 JOIN 優化成熟)。SFZHM,避免全行拷貝開銷。data_content_152(SFZHM)、data_content_152(id PK)、tmp3(col1 PK)。方案 優點 缺點 適用場景 本文 JOIN 臨時表 速度快、邏輯清晰、可控 需額外臨時表空間 千萬級去重首選 DELETE ... WHERE id NOT IN (SELECT MIN(id) ...)原地刪除,無額外表 NOT IN子查詢極慢、易鎖表僅適合幾萬行小表 ALTER IGNORE TABLE ... ADD UNIQUE KEY (uniq_col)一條命令完成(5.7 前) 5.7+ 移除 IGNORE、不可控保留哪行、鎖表久 不推薦 ROW_NUMBER() OVER (PARTITION BY uniq_col ORDER BY id)(8.0+)標準 SQL、無臨時表、可保留任意行 需 8.0+、大表排序開銷大 8.0 環境首選