MySQL INSERT 支援 VALUES、SELECT、SET 三種寫法,提供 LOW_PRIORITY、DELAYED、IGNORE 修飾符。本文系統整理語法細節、資料型別轉換規則、自增欄位行為與批次插入優化策略。
一、三種核心語法形式
1. VALUES 形式 (最常用)
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_list)]
VALUES (val_list1), (val_list2), ...
- 支援多值列表批次插入 (MySQL 3.22.5+)
- 未指定欄位則需提供所有欄位值 (按建表順序)
2. SELECT 形式 (跨表複製/轉換)
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name [(col_list)]
SELECT ... FROM ... WHERE ...
- ❌ 禁止
ORDER BY 子句
- ❌ 目標表不可出現在
FROM 子句 (ANSI SQL 限制)
- ✅
AUTO_INCREMENT 正常運作
3. SET 形式 (明確欄位對應)
INSERT [LOW_PRIORITY | DELAYED] [IGNORE] [INTO] tbl_name
SET col1=expr1, col2=expr2, ...
- MySQL 3.22.10+ 支援
- 可引用前序欄位:
INSERT INTO t (a,b) VALUES (15, a*2) ✅ / VALUES (b*2, 15) ❌
二、修飾符行為差異
| 修飾符 | 行為 | 適用場景 |
| LOW_PRIORITY | 等待無讀取鎖才執行,客戶端阻塞等待 | 讀多寫少、非即時寫入 |
| DELAYED | 客戶端立即返回,排隊寫入 (MySQL 專有) | 日誌寫入、高併發非關鍵資料 |
| IGNORE | 忽略重複鍵衝突,不報錯繼續 | 批次導入可能有重複資料 |
關鍵差異: LOW_PRIORITY 阻塞客戶端,DELAYED 立即返回並異步寫入,DELAYED 還能合併批次寫入提升吞吐。
三、資料型別隱式轉換規則 (產生 Warning)
| 情況 | 處理結果 |
| NULL → NOT NULL 欄位 | 轉為型別預設值 (0/''/'0000-00-00') |
| 數值超出範圍 | 截斷至邊界值 |
| '10.34 a' → 數值欄位 | 取前導數字 10.34,非數字開頭轉 0 |
| 字串超過 CHAR/VARCHAR/TEXT 長度 | 截斷至最大長度 |
| 非法日期/時間格式 | 轉為型別「零值」 |
四、資訊函數與回傳值
-- 批次插入後
SELECT ROW_COUNT(); -- 實際插入行數
SELECT LAST_INSERT_ID(); -- 首行自增 ID
-- C API
mysql_info() → "Records: 100 Duplicates: 0 Warnings: 0"
五、批次插入效能優化策略
- 多值列表單次 INSERT:
INSERT INTO t VALUES (...), (...), ... 比多次單行 INSERT 快 10-100 倍
- 關閉索引/外鍵檢查 (大量導入):
SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0;
-- 導入操作
SET FOREIGN_KEY_CHECKS=1; SET UNIQUE_CHECKS=1;
- 調大緩衝區:
bulk_insert_buffer_size (MyISAM)、innodb_log_buffer_size (InnoDB)
- 使用 LOAD DATA INFILE: 純文字導入最快,比 INSERT 快 20 倍+
- 事務包裹: InnoDB 批次插入建議每 1000-5000 行提交一次事務
六、DELAYED 插入內部機制
- 插入請求進入記憶體佇列,客戶端立即收到 OK
- 專用執行緒在表空閒時批次寫入磁碟
- 表被鎖定時佇列累積,釋放鎖後高效寫入
- ⚠️ 崩潰可能丟失佇列資料,不適合關鍵業務
- ⚠️ MySQL 8.0 已移除 DELAYED 支援
- 上一篇文章: MySQL UPDATE 語法完整詳解:單表、多表、修飾符、限制條件與最佳實踐
- 下一篇文章: 微信開發 MySQL 字元編碼亂碼終極解決:utf8mb4 完整配置指南
Copyright ©
程式碼之家 All Rights Reserved