แทรกความเร็วสำหรับชุดงานขนาดใหญ่


10

ในแอปพลิเคชันของฉัน INSERT ของฉันดูเหมือนจะใช้เวลาอย่างมาก ฉันมีวัตถุจำนวนมากในหน่วยความจำ (~ 40-50,000) ซึ่งฉันต้องการแทรกลงในตาราง

ลองดูตารางตัวอย่าง

CREATE TABLE bill (
id BIGINT(20) PRIMARY KEY,
amount INT(11) DEFAULT 0,
bill_date DATETIME DEFAULT NOW(),
INDEX (bill_date)
) ENGINE=InnoDB

การใช้ 3 แถวเป็นขนาดแบทช์ของฉันต่อไปนี้เป็นแนวทางที่ฉันคิดได้สำหรับการแทรก

วิธีที่ 1 - สร้างและยิงเม็ดมีด 3 เม็ด

INSERT INTO bill (amount, bill_date) VALUES (10, '2012-01-01 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (20, '2012-01-02 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (40, '2013-02-05 00:00:00');

วิธีที่ 2 - รวมค่าเป็น 1 แบบสอบถาม

INSERT INTO bill (amount, bill_date) VALUES 
(10, '2012-01-01 00:00:00'),
(20, '2012-01-02 00:00:00'),
(40, '2013-02-05 00:00:00');

วิธีที่ 3 - เริ่มต้นการสืบค้น 1 ครั้งผ่านพารามิเตอร์ 6 ตัว

INSERT INTO bill (amount, bill_date) VALUES 
(?, ?), (?, ?), (?, ?);

วิธีที่ 4 - ดับคำค้นหาที่เตรียมไว้นี้ 3 ครั้งเปลี่ยน 2 พารามิเตอร์ในแต่ละครั้ง

INSERT INTO bill (amount, bill_date) VALUES (?, ?);

ยินดีต้อนรับวิธีการอื่นใด

คำถามของฉันคือ

วิธีที่เร็วที่สุดในการสร้างเม็ดมีดหลายใบในตารางคืออะไร?

ฉันได้อ่านลิงค์นี้เกี่ยวกับความเร็วในการแทรก mysqlและคำแนะนำในการเขียนโปรแกรม JDBCนี้ แต่ฉันไม่สามารถสรุปได้

กรณีของฉัน -

ขณะนี้ตารางของฉันมีประมาณ 20 คอลัมน์ซึ่งส่วนใหญ่เป็นตัวเลขโดยมี varchar (60) และคอลัมน์ข้อความ 1 คอลัมน์ Mysql รุ่น 5.5 ทำงานบน INNODB และมี 1 ดัชนีคีย์หลักของจำนวนเต็ม แบบสอบถามทั้งหมดทำงานในธุรกรรม

ฉันสร้างคิวรีของฉันจาก Java และใช้ Spring JDBC เพื่อรันเคียวรี

ขณะนี้ฉันกำลังติดตามวิธีที่ 3 ใช้เวลาประมาณ 10 วินาทีในการแทรก 20,000 ลงในตารางว่างเปล่าไม่รวมเวลาที่ใช้ในการสร้างแบบสอบถาม

เพื่อให้สิ่งต่าง ๆ ในมุมมองมันใช้ 100-200 มิลลิวินาทีในการดึงข้อมูลจากตาราง

มีบางอย่างที่ฉันขาดหายไปหรือไม่? ฉันจะทำให้ส่วนแทรกเร็วขึ้นได้อย่างไร


คำถามที่เกี่ยวข้องในกองมากเกิน: MySQL และ JDBC กับ rewriteBatchedStatements = true
ตำลึง ธ อมป์สัน

คำตอบ:


3

พิจารณาแบทช์ของคุณ ขนาดแบตช์ 1024 เป็นขนาดเริ่มต้นที่ดี เปลี่ยนขนาดแบทช์จนกว่าคุณจะได้ปริมาณงานที่เหมาะสม


1

คุณได้ทำการทดสอบหรือเป็นไปได้หรือไม่ที่จะวางดัชนีบนตารางฐานข้อมูลปลายทางที่คุณกำลังแทรกเข้าไปแทรกเข้าไปในกลุ่มย่อยแบบแบตช์ขนาดเล็ก (ดีที่สุดตามที่ระบุไว้ข้างต้น) จากนั้นสร้างดัชนีใหม่บนตารางปลายทาง เมื่อเม็ดมีดทั้งหมดเสร็จสมบูรณ์ อาจเป็นเรื่องง่ายพอที่จะทดสอบเพื่อยืนยัน


0

เคล็ดลับการโหลดข้อมูลจำนวนมากจากเอกสาร mysql นั้นมีประโยชน์มาก https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html

คุณสามารถเพิ่มความเร็วในการแทรกได้หลายวิธี:

- turn off autocommit
- turn off unique check
- turn off foreign check

หวังว่าจะช่วยได้!


2
หากปิดการตรวจสอบข้อ จำกัด (คีย์แปลกใหม่, ... ) ให้แน่ใจว่าข้อมูลของคุณไม่ทำลายหรือฐานข้อมูลของคุณอยู่ในสถานะไม่สอดคล้องกันจากจุดนั้นเป็นต้นไป
David Spillett
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.