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

MySQL INSERT 語句完全指南:單行、批量、去重、衍生列與高性能寫入實戰

     編輯:MySQL 資料庫相關知識

前言:寫入的藝術,始於 INSERT

INSERT 是 MySQL 最基礎也最關鍵的 DML 操作。從單行插入到百萬級批量導入,從主鍵衝突處理到衍生列計算,本文系統梳理完整語法變體、核心子句行為、性能優化策略與實戰避坑指南,助您寫出**快、正、省**的寫入代碼。

一、三大語法形態全景圖

1. VALUES 形式(最常用)


-- 單行
INSERT INTO worker (name, email) VALUES ('tom', 'tom@yahoo.com');

-- 批量多行(單條 SQL,性能提升數量級)
INSERT INTO worker (name, email) VALUES
  ('tom', 'tom@yahoo.com'),
  ('paul', 'paul@yahoo.com'),
  ('john', 'john@yahoo.com');

-- 部分列(其餘列用默認值/自增)
INSERT INTO worker (name) VALUES ('tom'), ('paul');

2. SET 形式(列名值對映射,僅單行)


INSERT INTO worker SET name = 'tom', email = 'tom@yahoo.com';
-- 未指定列自動填充默認值

3. SELECT 形式(從其他表/查詢結果寫入)


-- 指定列映射
INSERT INTO tbl1 (col1, col2) SELECT col3, col4 FROM tbl2;

-- 全列匹配(結構必須完全一致)
INSERT INTO tbl1 SELECT col3, col4 FROM tbl2;

限制:SELECT 不能含 ORDER BY;目標表不能出現在 FROM 子句中(避免死循環)。

二、核心進階特性深度解析

1. ON DUPLICATE KEY UPDATE:寫入去重「瑞士軍刀」

當插入導致 **主鍵** 或 **唯一索引** 衝突時,轉為 UPDATE 現有行。


-- 基礎:衝突時更新指定列
INSERT INTO t (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=3;

-- 引用待插入值(VALUES() 函數)
INSERT INTO t (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=VALUES(c);

-- 跨列運算:衝突時 c = a + b(待插入值)
INSERT INTO t (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
  • VALUES(col) 只在 ON DUPLICATE KEY UPDATE 中有效,引用**本次插入擬寫入的值**。
  • 適用場景:計數器增量、最新狀態覆蓋、幂等寫入。

2. INSERT ... SELECT ... ON DUPLICATE KEY UPDATE:批量去重同步


INSERT INTO tbl1 (a,b,c)
SELECT col1, col2, col3 FROM tbl2
ON DUPLICATE KEY UPDATE c=VALUES(c);

3. 隱式默認值處理(非嚴格模式/非 NOT NULL)

數據類型隱式默認值
數值型0
字符串'' (空串)
日期時間'0000-00-00 00:00:00' (零值)

建議:啟用 STRICT_TRANS_TABLES 避免靜默寫入異常數據。

4. INSERT DELAYED:異步寫入(MyISAM/MEMORY/ARCHIVE 專用)


INSERT DELAYED INTO worker (name) VALUES ('tom'), ('paul');
特性說明
立即返回客戶端不等待寫入完成,獲取確認即返回
隊列合併多客戶端插入合併為塊寫入,減少 I/O
限制不支持 SELECT/ON DUPLICATE KEY UPDATE;LAST_INSERT_ID() 不可用;從庫忽略
適用引擎MyISAM, MEMORY, ARCHIVE(InnoDB 不支持)

現狀:MySQL 8.0 已移除,建議改用應用層異步隊列(Kafka/RabbitMQ)+ 批量寫入。

5. LOW_PRIORITY / HIGH_PRIORITY / IGNORE 修飾符

  • LOW_PRIORITY:等待無讀鎖才寫入(MyISAM 表級鎖場景)。
  • HIGH_PRIORITY:覆蓋 LOW_PRIORITY,搶佔寫入。
  • IGNORE:忽略主鍵/唯一鍵衝突、數據截斷等錯誤,轉為警告繼續執行。

三、性能優化黃金法則

1. 批量綁定:單條 SQL 承載千行


-- 應用層組裝:每批 1000~5000 行,單條 SQL 長度 < max_allowed_packet
INSERT INTO t (a,b) VALUES (?,?),(?,?)...;  -- PreparedStatement 批量綁定
  • 減少網絡往返、解析優化開銷、事務提交次數。
  • InnoDB 內部將批量插入優化為「批量頁寫入」,大幅降低 Redo Log 刷盤頻率。

2. 主鍵有序插入:避免頁分裂

  • 自增主鍵天然有序,最佳。
  • UUID/雪花 ID 無序 → 導致 B+ 樹頻繁分裂、碎片率高。建議:有序 UUID(時間戳前綴)或插入前排序。

3. 事務邊界控制


SET autocommit=0;
-- 批量循環
  INSERT ...; -- 累積 1000 行
  COMMIT;     -- 適度提交,避免超大事務鎖持有過久
SET autocommit=1;

4. 禁用非必要索引/外鍵(大批量導入時)

  • MyISAM:ALTER TABLE t DISABLE KEYS → 導入 → ENABLE KEYS。
  • InnoDB:臨時 DROP INDEX / SET foreign_key_checks=0,導入後重建。

四、常見陷阱與避坑指南

現象原因修正
Packet too large單條 SQL 超過 max_allowed_packet增大參數 / 減小批次行數
Duplicate entry主鍵/唯一鍵衝突用 ON DUPLICATE KEY UPDATE 或 IGNORE
Auto_increment 值不連續事務回滾/失敗/DELAYED 導致預分配 ID 浪費正常現象,業務勿依賴連續性
INSERT ... SELECT 死鎖目標表與源表加鎖順序不一致拆分為應用層讀寫 / 調整隔離級別
LAST_INSERT_ID() 返回 0使用了 INSERT DELAYED / 多行插入只返回第一行 ID改用普通 INSERT / 查詢 information_schema

五、實戰模板:高性能批量寫入存儲過程


DELIMITER //
CREATE PROCEDURE batch_insert_worker(IN p_count INT)
BEGIN
  DECLARE v_sql TEXT DEFAULT 'INSERT INTO worker (name,email) VALUES ';
  DECLARE i INT DEFAULT 0;
  SET autocommit = 0;
  WHILE i < p_count DO
    SET v_sql = CONCAT(v_sql, '(', QUOTE(CONCAT('user_', i)), ',', QUOTE(CONCAT('user_', i, '@example.com')), '),');
    SET i = i + 1;
    IF i % 1000 = 0 THEN
      SET v_sql = CONCAT(SUBSTRING(v_sql, 1, CHAR_LENGTH(v_sql)-1), ';');
      PREPARE stmt FROM v_sql;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;
      COMMIT;
      SET v_sql = 'INSERT INTO worker (name,email) VALUES ';
    END IF;
  END WHILE;
  IF i % 1000 != 0 THEN
    SET v_sql = CONCAT(SUBSTRING(v_sql, 1, CHAR_LENGTH(v_sql)-1), ';');
    PREPARE stmt FROM v_sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    COMMIT;
  END IF;
  SET autocommit = 1;
END//
DELIMITER ;

結語

INSERT 看似簡單,實則蘊含「批量vs單行」「同步vs異步」「去重vs報錯」「有序vs無序」多維度權衡。掌握 ON DUPLICATE KEY UPDATE 幂等寫入模式、批量綁定最佳實踐、主鍵設計對寫入性能的決定性影響,配合事務邊界與索引策略的動態調整,才能在高併發寫入洪流中,構建**高吞吐、低延遲、強一致**的數據寫入管道。願本文成為您寫入優化路上的「武林秘籍」。

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