ไวยากรณ์: INSERT หลายชุดค่า
INSERT INTO yourTable (col1, col2, ...) VALUES (val1, val2, ...), (val1, val2, ...), (val1, val2, ...);
ตัวอย่าง: ตาราง demo56
CREATE TABLE demo56 (
id INT,
first_name VARCHAR(20),
last_name VARCHAR(20),
age INT
);
INSERT INTO demo56 VALUES
(1, 'John', 'Smith', 23),
(2, 'David', 'Miller', 21),
(3, 'Chris', 'Brown', 22),
(4, 'Carol', 'Taylor', 20);
ผลลัพธ์
+------+------------+-----------+------+ | id | first_name | last_name | age | +------+------------+-----------+------+ | 1 | John | Smith | 23 | | 2 | David | Miller | 21 | | 3 | Chris | Brown | 22 | | 4 | Carol | Taylor | 20 | +------+------------+-----------+------+
ข้อดีของ Multi-row INSERT
- เร็วกว่ามาก: 1 Round-trip, 1 Parsing, 1 Transaction overhead
- Atomic: สำเร็จทั้งหมด หรือล้มเหลวทั้งหมด (ถ้าไม่มี IGNORE)
- Binary Log: เขียนเป็น 1 Event แทนหลาย Event
- Auto-increment: ให้ค่าเรียงติดกันแน่นอน
Benchmark (ประมาณ)
| วิธี | 1,000 rows | 10,000 rows | 100,000 rows |
|---|---|---|---|
| INSERT แยก (1000 queries) | ~2-5 วินาที | ~20-50 วินาที | ~นานมาก |
| Multi-row (1 query) | ~0.05-0.1 วินาที | ~0.3-0.8 วินาที | ~3-8 วินาที |
| LOAD DATA INFILE | ~0.01 วินาที | ~0.05 วินาที | ~0.5 วินาที |
ข้อจำกัด
max_allowed_packet: ขนาด Packet สูงสุด (Default 64MB) — แบ่ง Batch หากใหญ่เกิน- ค่าที่ซ้ำใน UNIQUE/PRIMARY KEY: ทั้ง Batch จะล้มเหลว (ใช้
INSERT IGNOREหรือON DUPLICATE KEY UPDATE) - Trigger: AFTER INSERT ทำงาน 1 ครั้งต่อแถว (เหมือน INSERT แยก)
รูปแบบเพิ่มเติม
1. INSERT IGNORE (ข้าม Duplicate)
INSERT IGNORE INTO demo56 VALUES (1, 'John', 'Smith', 23), (1, 'Duplicate', 'WillSkip', 99); -- id=1 ซ้ำ → ข้าม
2. ON DUPLICATE KEY UPDATE (Upsert)
INSERT INTO demo56 VALUES
(1, 'John', 'Smith', 23),
(2, 'David', 'Miller', 21)
ON DUPLICATE KEY UPDATE
first_name = VALUES(first_name),
last_name = VALUES(last_name),
age = VALUES(age);
3. INSERT ... SELECT (จากตารางอื่น)
INSERT INTO demo56 (id, first_name, last_name, age) SELECT id, first_name, last_name, age FROM backup_table;
Best Practice: Batch Size
แนะนำ 100-1000 rows ต่อ Statement (ขึ้นกับขนาด Row) เพื่อ:
- ไม่เกิน max_allowed_packet
- ลด Lock contention
- Rollback เร็วขึ้นถ้าล้มเหลว