首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL INSERT 插入數據完全指南:單條、批次、IGNORE、ON DUPLICATE KEY 實戰

     編輯:MySQL 綜合教學

MySQL INSERT 插入數據深度實戰:語法變體、效能優化、衝突處理與最佳實踐

INSERT 是寫入操作核心。本文系統講解單條/批次插入、IGNORE 忽略錯誤、ON DUPLICATE KEY UPDATE 衝突轉更新、大數據導入優化、自增 ID 獲取等生產級用法。

基礎語法變體


-- 1. 標準顯式列名 (推薦,防結構變更)
INSERT INTO `tbl` (`col1`, `col2`, `col3`) VALUES ('v1', 'v2', 'v3');

-- 2. 批次插入 (高效,單事務)
INSERT INTO `tbl` (`col1`, `col2`) VALUES 
    ('a1', 'b1'), ('a2', 'b2'), ('a3', 'b3');

-- 3. INSERT ... SELECT (表間複製/轉換)
INSERT INTO `target_tbl` (`id`, `name`, `created_at`)
SELECT `user_id`, `username`, NOW() FROM `source_users` WHERE `status`=1;

-- 4. INSERT IGNORE (忽略主鍵/唯一鍵衝突,不報錯)
INSERT IGNORE INTO `tbl` (`uk_col`, `data`) VALUES ('duplicate_key', 'new_data');
-- 衝突行不插入,不報錯,警告計數 +1 (SHOW WARNINGS)

-- 5. REPLACE INTO (衝突時刪除舊行再插新行,觸發 DELETE+INSERT 觸發器)
REPLACE INTO `tbl` (`pk`, `data`) VALUES (1, 'new_value');
-- 等價於:DELETE + INSERT,自增 ID 會改變

-- 6. ON DUPLICATE KEY UPDATE (Upsert 核心,衝突轉更新)
INSERT INTO `tbl` (`uk_col`, `counter`, `updated_at`) 
VALUES ('key1', 1, NOW())
ON DUPLICATE KEY UPDATE 
    `counter` = `counter` + 1,
    `updated_at` = NOW();
-- VALUES() 函數引用插入值
INSERT INTO `tbl` (`uk_col`, `val`) VALUES ('k1', 100)
ON DUPLICATE KEY UPDATE `val` = VALUES(`val`) + 10;

效能優化關鍵點

  1. 批次大小:單次 VALUES 行數建議 100-1000 行,超大批次拆分,避免 max_allowed_packet 超限、Binlog 過大、鎖持有過久。
  2. 事務包裹:應用層開啟事務批次提交,或 autocommit=0 手動控制,大幅減少 fsync 開銷。
  3. 禁用二級索引 (大量導入):ALTER TABLE tbl DISABLE KEYS (MyISAM) / 導入後重建索引 (InnoDB 5.7+ ALTER TABLE ... ALGORITHM=INPLACE 不支援 DISABLE KEYS,建議先導入再建索引)。
  4. 主鍵順序插入:InnoDB 聚簇索引按主鍵順序存儲,順序插入 (自增/單調遞增 UUID) 避免頁分裂、碎片。亂序插入導致大量隨機 I/O。
  5. LOAD DATA INFILE (極速導入):

LOAD DATA INFILE '/path/data.csv'
INTO TABLE `tbl`
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n'
IGNORE 1 LINES
(`col1`, `col2`, `col3`)
SET `created_at` = NOW();
-- 比 INSERT 快 10-20 倍,直接寫頁面、最小化日誌

自增 ID 獲取與併發安全


-- 會話級安全
INSERT INTO `tbl` (`name`) VALUES ('test');
SELECT LAST_INSERT_ID();  -- 返回當前會話最後生成的自增值,併發隔離

-- 批次插入獲取首個 ID
INSERT INTO `tbl` (`name`) VALUES ('a'), ('b'), ('c');
SELECT LAST_INSERT_ID();  -- 返回第一行生成的 ID (連續分配)

-- 存儲過程/觸發器中
SELECT LAST_INSERT_ID() INTO @new_id;

常見陷阱與避坑

陷阱後果解決
省略列名 INSERT INTO tbl VALUES(...)表結構變更 (增/減/調序列) 導致數據錯位或報錯永遠顯式指定列名
單條循環 INSERT (應用層 for 循環)網路往返、事務提交、Binlog 寫入開銷巨大,效能極低批次 VALUES / LOAD DATA / 事務包裹
ON DUPLICATE KEY UPDATE 未覆蓋所有列衝突時未更新列保留舊值,可能非預期顯式列出所有需更新列
REPLACE INTO 導致自增 ID 跳變、觸發器雙重觸發主鍵引用關係斷裂、審計日誌異常改用 INSERT ... ON DUPLICATE KEY UPDATE
大批次未分片導致 max_allowed_packet 報錯插入失敗、事務回滾應用層分片 (每批 1MB 內) 或調大參數

大數據量導入標準流程 (百萬/億級)

  1. 目標表 無索引 (僅主鍵) 或 禁用二級索引。
  2. CSV 文件按主鍵順序排序 (匹配聚簇索引順序)。
  3. LOAD DATA INFILE 分批導入 (每批 10-50 萬行)。
  4. 導入完成後 建立二級索引 (CREATE INDEX ...)。
  5. ANALYZE TABLE 更新統計信息。

結語:INSERT 看似簡單,但批次策略、衝突處理、主鍵順序、大數據導入流程直接決定寫入吞吐與數據質量。掌握 ON DUPLICATE KEY UPDATE、LOAD DATA、批次事務三大核心技巧,應對 99% 寫入場景。

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