ทำไม 'โหลดข้อมูล INFILE' เร็วกว่าคำสั่ง INSERT ปกติ?


22

ฉันได้อ่านบทความที่กล่าวถึงเราสามารถบรรลุ60,000 แทรกต่อวินาทีโดยใช้LOAD DATA IN FILEคำสั่งที่อ่านจากไฟล์ csv และแทรกข้อมูลลงในฐานข้อมูล

ทำไมมันควรแตกต่างจากเม็ดมีดทั่วไป?

แก้ไข:
ฉันลดการเดินทางไป - กลับโดยเรียกเพียงINSERTคำสั่งเดียว:

INSERT INTO tblname
VALUES (NULL,2,'some text here0'),(NULL,2,'some text here1')
    ,(NULL,2,'some text here2'),(NULL,2,'some text here3')
    .....,(NULL,2,'some text here3000');

แล้วเรื่องนี้ล่ะ


ผมเขียนบทความเกี่ยวกับการขนาดกลางที่เปรียบเทียบแทรกขยาย VS LOAD DATA INFILE: แทรกความเร็วสูงกับ MySQL บรรทัดล่าง: คุณสามารถบรรลุประสิทธิภาพ 65% ของการ LOAD DATA INFILEใช้ส่วนแทรกเพิ่มเติม ฉันได้รับ 240,000 เม็ดต่อวินาทีสำหรับฮาร์ดแวร์ที่ทันสมัย
เบนจามิน

คำตอบ:


26

โหลดข้อมูล INFILE และ INSERT ที่ขยายเพิ่มแต่ละอันมีข้อดีที่แตกต่างกัน

โหลดข้อมูล INFILE ถูกออกแบบมาสำหรับการโหลดข้อมูลตารางจำนวนมากในการดำเนินการเดียวพร้อมกับระฆังและนกหวีดเพื่อดำเนินการต่อไปนี้:

  • ข้ามบรรทัดเริ่มต้น
  • ข้ามคอลัมน์เฉพาะ
  • การแปลงคอลัมน์เฉพาะ
  • กำลังโหลดคอลัมน์เฉพาะ
  • การจัดการปัญหาหลักที่ซ้ำกัน

ค่าใช้จ่ายน้อยลงเป็นสิ่งจำเป็นสำหรับการแยก

ในทางกลับกันหากคุณนำเข้าเพียง 100 แถวแทนที่จะเป็น 1,000,000 แถวส่วนขยาย INSERT นั้นสมเหตุสมผล

โปรดสังเกตว่า mysqldump ได้รับการออกแบบรอบ ๆ INSERT ที่เพิ่มขึ้นเพื่อประโยชน์ในการออกแบบโต๊ะพร้อมกับข้อมูลเนื่องจากมันทำการฉีดหลายร้อยหรือหลายพันแถวต่อ INSERT โหลดข้อมูล INFILE สร้าง dichomoty จริงทางกายภาพระหว่างสคีมาและข้อมูลเสมอ

จากมุมมองของแอปพลิเคชัน LOAD DATA INFILE จะไม่ไวต่อการเปลี่ยนแปลงของ schema มากกว่า INSERT ที่ขยายเพิ่ม

หนึ่งสามารถย้อนกลับไปในดี, ไม่ดีและน่าเกลียดของการใช้โหลดข้อมูล INFILE ไม่ว่าคุณจะใช้เทคนิคใดคุณจะต้องตั้งค่าbulk_insert_buffer_sizeเสมอ ทำไม?

ตามเอกสาร MySQL ใน bulk_insert_buffer_size:

MyISAM ใช้แคชที่มีลักษณะคล้ายต้นไม้เป็นพิเศษเพื่อให้แทรกจำนวนมากได้เร็วขึ้นสำหรับ INSERT ... SELECT, INSERT ... VALUES (... ), (... ), ... , ... , และโหลดข้อมูล INFILE เมื่อเพิ่มข้อมูลลงไป ตาราง ตัวแปรนี้ จำกัด ขนาดของทรีแคชเป็นไบต์ต่อเธรด การตั้งค่าเป็น 0 จะปิดใช้งานการเพิ่มประสิทธิภาพนี้ ค่าเริ่มต้นคือ 8MB

เป็นเวลาหลายปีที่ฉันได้เห็นลูกค้าหลังจากลูกค้าไม่ได้ตั้งค่านี้และปล่อยไว้ที่ 8MB จากนั้นเมื่อพวกเขาตัดสินใจใช้โหลดโหลดข้อมูลหรือนำเข้า mysqldumps พวกเขาสามารถรู้สึกผิดปกติ ฉันมักจะแนะนำให้ตั้งค่านี้ในระดับปานกลาง 256M ในบางกรณี 512M

เมื่อคุณมีบัฟเฟอร์ INSERT จำนวนมากเพียงพอการใช้เทคนิคใดวิธีหนึ่งจะแสดงผลทางวิชาการ สำหรับแอปพลิเคชันที่คุณใส่ INSERT จำนวนมากตามต้องการเพียง 100 แถวติดกับ INSERT ที่ขยายเพิ่ม

ในทุกความเป็นธรรมการกล่าวว่าโหลดข้อมูล INFILE นั้นเร็วกว่าที่คำสั่ง INSERT ปกติเป็นประเภทของคำสั่งที่โหลดเป็นส่วนใหญ่เนื่องจากการกำหนดค่าไม่ได้นำมาพิจารณา แม้ว่าคุณจะตั้งค่าเกณฑ์มาตรฐานระหว่างโหลดข้อมูล INFILE และ INSERTs ที่เพิ่มขึ้นด้วย bulk_insert_buffer_size ที่เหมาะสมจำนวนนาโนวินาทีที่บันทึกไว้ในการแยกวิเคราะห์แต่ละแถวสามารถให้ผลลัพธ์ที่ดีที่สุดแก่ LOAD DATA INFILE

ไปข้างหน้าและเพิ่มลงใน my.cnf

[mysqld]
bulk_inset_buffer_size=256M

คุณสามารถตั้งค่าสำหรับเซสชั่นของคุณก่อนที่จะเปิดตัว INSERT เพิ่มเติม

SET bulk_insert_buffer_size= 1024 * 1024 * 256;

อัพเดท 2012-07-19 14:58 EDT

เพื่อให้สิ่งต่าง ๆ ในมุมมองบัฟเฟอร์แทรกจำนวนมากมีประโยชน์สำหรับการโหลดตาราง MyISAM ไม่ใช่ InnoDB ฉันเขียนโพสต์ล่าสุดเกี่ยวกับการโหลดจำนวนมาก InnoDB: โหลด Mysql จาก infile ค้างอยู่บนฮาร์ดไดรฟ์


4

ระบบการจัดการฐานข้อมูลส่วนใหญ่มีระบบอำนวยความสะดวกในการโหลดข้อมูลจำนวนมากสำหรับการโหลดข้อมูลจำนวนมากอย่างรวดเร็ว INSERTคำสั่งมีจำนวนเงินที่สำคัญของกระเป๋าเดินทางต่อคำสั่ง - ล็อคแบ่งเขตการทำธุรกรรมการตรวจสอบความสมบูรณ์ของ referential การจัดสรรทรัพยากร I / O ที่จะต้องมีการดำเนินการบนพื้นฐานต่อคำสั่ง

การดำเนินการแทรกจำนวนมากทำให้กระบวนการนี้คล่องตัวยิ่งขึ้นดังนั้นสิ่งนี้มีค่าใช้จ่ายมากน้อยกว่ามากต่อแถว DBMS สามารถโหลดคำสั่งข้อมูลจำนวนมากได้เร็วกว่าผ่านคำสั่งแทรก


3

การแยกและการดำเนินการแต่ละINSERTคำสั่งมีค่าใช้จ่ายที่ใหญ่กว่าการแยกไฟล์ CSV ลงในคอลัมน์และโหลดโดยตรง

แต่ละINSERTคำสั่งจะต้องมีการแยกวิเคราะห์โดยเครื่องยนต์ MySQL และตรวจสอบความถูกต้อง - นี้ใช้ทรัพยากร CPU เพิ่มเติมและยังต้องใช้ไคลเอนต์ <> เซิร์ฟเวอร์รอบการเดินทาง LOAD DATA INFILEนี้ไม่จำเป็นต้องที่จะเกิดขึ้นได้เมื่อโหลดจำนวนมากผ่านทาง นอกจากนี้ยังมีการเพิ่มประสิทธิภาพที่สามารถเกิดขึ้นเมื่อใช้LOAD DATA INFILEในการโหลดลงในตารางที่ว่างเปล่า ดูลิงค์นี้สำหรับข้อมูลเพิ่มเติม


ดูส่วนแก้ไขของคำถามของฉัน
ALH

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