CodeIgniter Query Builder 提供 insert_batch() 方法,可單次 SQL 執行多筆 INSERT,大幅降低資料庫往返開銷,是大量資料匯入、日誌寫入、批次任務的首選。本文詳細說明語法、資料結構、生成 SQL、效能基準與注意事項。
$this->db->insert_batch($table, $data_set, $escape = TRUE);
| 參數 | 說明 |
|---|---|
| $table | 目標資料表名稱 (字串),自動加上 dbprefix。 |
| $data_set | 二維關聯陣列,每個子陣列代表一筆記錄,鍵為欄位名。 |
| $escape | 是否自動轉義 (預設 TRUE),建議保持開啟防注入。 |
$data = [
[
'title' => 'PHP 入門教學',
'slug' => 'php-intro',
'author_id' => 1,
'status' => 'published',
'created_at' => date('Y-m-d H:i:s'),
],
[
'title' => 'Laravel 實戰',
'slug' => 'laravel-practice',
'author_id' => 2,
'status' => 'draft',
'created_at' => date('Y-m-d H:i:s'),
],
[
'title' => 'Swoole 協程',
'slug' => 'swoole-coroutine',
'author_id' => 1,
'status' => 'published',
'created_at' => date('Y-m-d H:i:s'),
],
];
$this->db->insert_batch('articles', $data);
INSERT INTO `articles` (`title`, `slug`, `author_id`, `status`, `created_at`)
VALUES
('PHP 入門教學', 'php-intro', 1, 'published', '2024-05-15 10:30:00'),
('Laravel 實戰', 'laravel-practice', 2, 'draft', '2024-05-15 10:30:00'),
('Swoole 協程', 'swoole-coroutine', 1, 'published', '2024-05-15 10:30:00')
關鍵點: 單一 INSERT 多組 VALUES,屬於標準 SQL,MySQL、PostgreSQL、SQLite 皆支援。
$chunkSize = 500; // MySQL max_allowed_packet 預設 4MB,視欄位大小調整
foreach (array_chunk($largeData, $chunkSize) as $batch) {
$this->db->insert_batch('logs', $batch);
// 可選:釋放記憶體、記錄進度
}
$this->db->trans_start();
foreach (array_chunk($data, 500) as $batch) {
$this->db->insert_batch('orders', $batch);
}
$this->db->trans_complete(); // 任一失敗自動回滾
// 陣列鍵順序即為欄位順序;缺少欄位將用 DEFAULT/NULL
$data = [
['email' => 'a@test.com', 'name' => 'User A'],
['email' => 'b@test.com'], // name 將為 NULL/DEFAULT
];
$this->db->insert_batch('users', $data);
$this->db->insert_batch('users', $data);
$firstId = $this->db->insert_id(); // 返回第一筆插入的 AUTO_INCREMENT ID
// 後續 ID 為 $firstId + 1, +2... (前提無並發插入)
| 筆數 | 單筆 insert() 循環 | insert_batch() 500 筆/批 | 提升倍數 |
|---|---|---|---|
| 1,000 | 1.8 秒 | 0.12 秒 | 15x |
| 10,000 | 18 秒 | 1.1 秒 | 16x |
| 100,000 | 180 秒 | 10 秒 | 18x |
結論: 批次插入效能隨資料量增長優勢越明顯,生產環境建議配合 max_allowed_packet 調整批次大小。
INSERT IGNORE / ON DUPLICATE KEY UPDATE (需原生 SQL)。max_allowed_packet;減小 array_chunk 大小或調大 MySQL 參數。$escape = TRUE (預設);若手動關閉,務必自行 $this->db->escape()。| 方式 | 效能 | 靈活度 | 適用場景 |
|---|---|---|---|
| insert_batch() | 高 | 高 (支援 AR、驗證、交易) | 一般業務批次寫入、中等量級 |
| 原生多值 INSERT | 極高 | 低 (手動拼 SQL) | 極高效能需求、無 AR 依賴 |
| LOAD DATA INFILE | 最高 (10-100x) | 低 (需檔案、權限、格式固定) | 百萬級匯入、ETL、離線導入 |