資料寫入是資料庫運維的基礎操作。MySQL 提供多種匯入路徑:標準 INSERT 適合少量業務寫入,LOAD DATA INFILE 針對大批量文字檔案極速載入,mysqlimport 則是命令列自動化的最佳夥伴。本文系統整理三大方式語法、參數、適用場景與避坑指南。
-- 1. 全欄位按序插入(須匹配表結構順序)
INSERT INTO tablename VALUES (value1, value2, ...);
-- 2. 指定欄位插入(推薦,順序可調整、擴充欄位不影響)
INSERT INTO tablename (field1, field2, ...) VALUES (value1, value2, ...);
-- 3. SET 語法(類似 UPDATE,欄位值對應直觀)
INSERT INTO tablename SET field1=value1, field2=value2, ...;
-- 4. 從另一張表查詢插入(跨表複製/ETL 常用)
INSERT INTO tablename (field1, field2) SELECT field1, field2 FROM sourcetable;
INSERT INTO tablename VALUES
(val1, val2, ...),
(val1, val2, ...),
(val1, val2, ...);
優勢:單條 SQL 完成多行寫入,減少網路往返、解析優化開銷、WAL 刷盤次數。建議單批次 500-2000 行,配合 max_allowed_packet 調整。
| 語法 | 行為 | 適用場景 |
|---|---|---|
| INSERT IGNORE | 主鍵/唯一鍵衝突時忽略錯誤,不寫入 | 冪等導入、去重 |
| REPLACE INTO | 衝突時刪除舊行再插新行(觸發 DELETE+INSERT) | 需覆蓋全行資料 |
| INSERT ... ON DUPLICATE KEY UPDATE | 衝突時只更新指定欄位(推薦) | 增量同步、計數器更新 |
| INSERT DELAYED | 緩衝佇列異步寫入(MyISAM/MEMORY,8.0 棄用) | 高併發日誌寫入 |
| INSERT LOW_PRIORITY | 等待讀鎖釋放後寫入 | 非即時批次作業 |
LOAD DATA [LOCAL] INFILE 'filename'
INTO TABLE tablename
[CHARACTER SET charset_name]
[FIELDS
[TERMINATED BY 'string']
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
]
[IGNORE number LINES]
[(col_name_or_user_var, ...)]
[SET col_name = expr, ...]
| 參數 | 預設值 | 說明 | 常用設定 |
|---|---|---|---|
| FIELDS TERMINATED BY | \t (Tab) | 欄位分隔符 | ',' (CSV)、'|'、'\t' |
| FIELDS ENCLOSED BY | 無 | 欄位包圍字元(處理含分隔符的值) | '"' (雙引號) |
| FIELDS ESCAPED BY | \ | 轉義字元 | '\\' 或 關閉 |
| LINES TERMINATED BY | \n | 行結束符 | '\r\n' (Windows)、'\n' (Linux) |
| IGNORE n LINES | 0 | 跳過前 n 行(如標題行) | 1 |
| LOCAL | 否 | 客戶端讀檔傳給 Server,無需 FILE 權限 | 開發/測試環境推薦 |
datadir 起算。需 FILE 權限,檔案必須 Server 可讀FILE 權限LOAD DATA LOCAL INFILE 'sample.txt'
INTO TABLE sample
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
(id, name, email, created_at);
mysqlimport 本質是 LOAD DATA INFILE 的命令列封裝,支援萬用字元批次處理多檔案。
mysqlimport [options] db_name textfile1 [textfile2 ...]
| 選項 | 對應 LOAD DATA 子句 | 說明 |
|---|---|---|
| --fields-terminated-by=',' | FIELDS TERMINATED BY ',' | 欄位分隔符 |
| --fields-enclosed-by='"' | FIELDS ENCLOSED BY '"' | 欄位包圍字元 |
| --fields-escaped-by='\\' | FIELDS ESCAPED BY '\\' | 轉義字元 |
| --lines-terminated-by='\r\n' | LINES TERMINATED BY '\r\n' | 行結束符 |
| --ignore-lines=1 | IGNORE 1 LINES | 跳過標題行 |
| --local | LOCAL | 客戶端讀檔模式 |
| --delete | -- | 匯入前清空表(慎用) |
| --lock-tables | -- | 匯入前鎖表(MyISAM) |
user.txt → 表 useruser.1.txt、user.2.txt 會依序匯入同一張表# 匯入單一檔案(CSV 格式,含標題行)
mysqlimport -u root -p --local \
--fields-terminated-by=',' \
--fields-enclosed-by='"' \
--lines-terminated-by='\r\n' \
--ignore-lines=1 \
mydb user.csv
# 批次匯入多張表
mysqlimport -u root -p --local \
--fields-terminated-by=',' \
mydb user.csv order.csv product.csv
| 維度 | INSERT (批次) | LOAD DATA INFILE | mysqlimport |
|---|---|---|---|
| 適用資料量 | < 10 萬行 | 10 萬 ~ 億級 | 同 LOAD DATA,適合腳本自動化 |
| 匯入速度 | 中 | 極快(直寫資料頁、最小日誌) | 極快 |
| 資料來源 | 應用程式變數/查詢結果 | 本地/遠端文字檔 | 本地文字檔 |
| 權限需求 | INSERT 權限 | FILE 權限 (無 LOCAL 時) | FILE 權限 (無 --local 時) |
| 錯誤處理 | 精細(逐行/事務控制) | 粗略(整體成功/失敗) | 同 LOAD DATA |
| 轉換邏輯 | 應用層任意處理 | SET 子句有限支援 | 同 LOAD DATA |
| 並行匯入 | 應用層控制 | 單線程(可分區表並行) | 單線程 |
--local 避免權限問題,預先 SET autocommit=0; SET unique_checks=0; SET foreign_key_checks=0; 加速,匯入後恢復CHARACTER SET 子句、表欄位字元集三者必須一致,否則亂碼YYYY-MM-DD HH:MM:SS),或用 SET col = STR_TO_DATE(@var, '%format%') 轉換REPLACE 或 IGNORE 關鍵字控制行為mysqlimport + Shell/Python 腳本 + crontab 實現定時 ETLMySQL 資料匯入無最好,只有最適合:日常業務寫入用 INSERT(含 ON DUPLICATE KEY UPDATE);大批量離線導入用 LOAD DATA INFILE;定時自動化腳本用 mysqlimport。掌握三者語法細節與效能特性,讓資料流轉更高效穩定。