ภาพรวม
MySQL รองรับการ Multi-row INSERT ในคำสั่งเดียว โดยระบุหลายชุดค่า คั่นด้วยจุลภาค เร็วกว่า INSERT หลายคำสั่งมาก
ไวยากรณ์
INSERT INTO table_name (col1, col2, ...)
VALUES
(val1_1, val1_2, ...),
(val2_1, val2_2, ...),
(val3_1, val3_2, ...),
...;
ตัวอย่างสมบูรณ์
1. สร้างตาราง
CREATE TABLE DemoTable (
ClientId INT,
ClientName VARCHAR(50)
);
2. Insert 5 แถวในคำสั่งเดียว
INSERT INTO DemoTable (ClientId, ClientName) VALUES
(101, 'Adam'),
(102, 'Chris'),
(103, 'Robert'),
(104, 'Sam'),
(105, 'Mike');
3. ผลลัพธ์
SELECT * FROM DemoTable;
+----------+------------+
| ClientId | ClientName |
+----------+------------+
| 101 | Adam |
| 102 | Chris |
| 103 | Robert |
| 104 | Sam |
| 105 | Mike |
+----------+------------+
ประโยชน์ของ Multi-row INSERT
| ด้าน | INSERT หลายคำสั่ง | Multi-row INSERT |
|---|---|---|
| Network Round-trips | N ครั้ง | 1 ครั้ง |
| Transaction Overhead | N ครั้ง (ถ้า Autocommit) | 1 ครั้ง |
| Parser/Optimizer | รัน N ครั้ง | รัน 1 ครั้ง |
| Binary Log | N Events | 1 Event (Statement-based) |
| ความเร็ว | ฐาน | เร็ว 5-10 เท่า |
ข้อจำกัด
- ขนาด Packet:
max_allowed_packet(Default 4MB/64MB) - หากข้อมูลใหญ่ต้องเพิ่ม - จำนวนแถว: แนะนำไม่เกิน 1000-5000 แถวต่อคำสั่ง (แบทช์)
- Memory: Server ต้อง Buffer คำสั่งทั้งหมด
การใช้งานในภาษาโปรแกรม (Batch Insert)
Python (MySQL Connector)
data = [(101, 'Adam'), (102, 'Chris'), (103, 'Robert')]
cursor.executemany(
"INSERT INTO DemoTable (ClientId, ClientName) VALUES (%s, %s)",
data
)
Java (JDBC Batch)
String sql = "INSERT INTO DemoTable (ClientId, ClientName) VALUES (?, ?)";
PreparedStatement ps = conn.prepareStatement(sql);
for (Data d : dataList) {
ps.setInt(1, d.id);
ps.setString(2, d.name);
ps.addBatch();
}
ps.executeBatch();
คำสั่งที่เกี่ยวข้อง
INSERT IGNORE- ข้ามแถวที่ Error (Duplicate Key)INSERT ... ON DUPLICATE KEY UPDATE- อัปเดตถ้าซ้ำREPLACE INTO- ลบเก่า Insert ใหม่ (Primary Key ซ้ำ)LOAD DATA INFILE- เร็วที่สุดสำหรับข้อมูลมาก (CSV, TSV)
สรุป
ใช้ INSERT ... VALUES (...), (...), (...) เพื่อ Insert หลายแถวในคำสั่งเดียว เร็ว ประหยัด Resource และ Atomic