เป็นวิธีที่มีประสิทธิภาพมากที่สุดในการชุดคำสั่ง UPDATE ใน MySQL คืออะไร?


10

ฉันกำลังเขียนแอปพลิเคชันที่ต้องการล้างการอัปเดตจำนวนมากไปยังฐานข้อมูลเป็นระยะเวลานานและฉันติดอยู่กับวิธีเพิ่มประสิทธิภาพการสืบค้น ขณะนี้ฉันกำลังใช้INSERT INTO ... VALUES (..), (..) ON DUPLICATE KEY UPDATEซึ่งทำงานเพื่อแบทช์ค่าทั้งหมดเป็นหนึ่งแบบสอบถาม แต่ดำเนินการช้าๆเลือดตาแทบกระเด็นบนตารางขนาดใหญ่ ฉันไม่จำเป็นต้องแทรกแถวจริงๆ

วิธีอื่นที่ฉันเห็นคือการอัปเดตโดยใช้SET value = CASE WHEN...(ซึ่งยากที่จะสร้างเนื่องจากวิธีที่ฉันสร้างคิวรีและฉันไม่แน่ใจเกี่ยวกับประสิทธิภาพCASEของคีย์หลายแสน / พันปุ่ม) และเรียงต่อกันหลาย ๆ อย่าง การปรับปรุง สิ่งเหล่านี้จะเร็วกว่าวิธีการปัจจุบันของฉันหรือไม่

มันทำให้ฉันงุนงงเท่าที่ฉันสามารถบอกได้ว่าไม่มีวิธีที่มีประสิทธิภาพและไร้เหตุผลในการทำสิ่งนี้ใน MySQL หากไม่มีวิธีที่เร็วกว่าจริงON DUPLICATE KEYๆ มันจะคุ้มไหมที่จะเปลี่ยนมาใช้ PostgreSQL และใช้UPDATE FROMไวยากรณ์ของมัน

คำแนะนำอื่น ๆ ยังชื่นชมอย่างมาก!

แก้ไข: นี่คือหนึ่งในตารางที่ได้รับการปรับปรุงบ่อยครั้ง ฉันได้ลบชื่อคอลัมน์เนื่องจากไม่เกี่ยวข้อง

CREATE TABLE IF NOT EXISTS `table` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `a` bigint(20) unsigned NOT NULL DEFAULT '0',
  `b` bigint(20) unsigned NOT NULL DEFAULT '0',
  `c` enum('0','1','2') NOT NULL DEFAULT '0',
  `d` char(32) NOT NULL,
  -- trimmed --
  PRIMARY KEY (`id`),
  KEY `a` (`a`),
  KEY `b` (`b`),
  KEY `c` (`c`),
  KEY `d` (`d`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

นี่เป็นเครื่องทดสอบและไม่ใช่การผลิตดังนั้น InnoDB จึงไม่ได้รับการปรับอย่างสมบูรณ์ ฉันไม่แน่ใจว่า INSERT FROM นั้นทำงานอย่างไร แต่สิ่งที่คุณพูดนั้นดูถูกต้อง อัปเดตคำถามพร้อมข้อมูลที่คุณขอ
jli

คำตอบ:


14

เนื่องจากคุณกำลังใช้InnoDBตารางการเพิ่มประสิทธิภาพที่ชัดเจนที่สุดคือการจัดกลุ่มหลายรายการUPDATEไว้ในธุรกรรม

ด้วยInnoDBการเป็นเอ็นจิ้นการทำธุรกรรมคุณไม่เพียงจ่ายสำหรับUPDATEตัวเองเท่านั้น แต่ยังรวมถึงค่าใช้จ่ายในการทำธุรกรรมทั้งหมด: การจัดการบัฟเฟอร์ธุรกรรมบันทึกธุรกรรมการล้างรายการบันทึกไปยังดิสก์

หากคุณพอใจกับแนวคิดอย่างมีเหตุผลลองและจัดกลุ่มละ 100-1,000 UPDATEวินาทีทุกครั้งที่มีการห่อหุ้มดังนี้:

START TRANSACTION;
UPDATE ...
UPDATE ...
UPDATE ...
UPDATE ...
COMMIT;

ข้อเสียที่เป็นไปได้:

  • ข้อผิดพลาดหนึ่งจะยุบธุรกรรมทั้งหมด (แต่จะแก้ไขได้ง่ายในรหัส)
  • คุณอาจรอเป็นเวลานานเพื่อสะสม 1,000 UPDATEวินาทีของคุณดังนั้นคุณอาจต้องการหยุดพักชั่วคราว
  • ความซับซ้อนมากขึ้นในรหัสแอปพลิเคชันของคุณ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.