Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

INSERT หลายแถวพร้อมกันใน MySQL (Multi-row INSERT)

ไวยากรณ์: 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 rows10,000 rows100,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 เร็วขึ้นถ้าล้มเหลว