การนำเข้าการถ่ายโอนข้อมูล mysql ช้ามากบนเครื่องของนักพัฒนาของฉัน


22

ฉันมี SQL dump มันใหญ่มาก (411 MB) และใช้เวลา 10 นาทีในการนำเข้าบนเซิร์ฟเวอร์ A การนำเข้าเดียวกันบนเวิร์กสเตชัน B ของฉันมีการประเมิน (pipeviewer) 8 ชั่วโมงเพื่อนำเข้า (มันนำเข้า 31 MB ใน 40 นาที ) นี่คือปัจจัย 53 ที่ช้ากว่า

รายละเอียด:

Server A:
   MySQL Version: 5.5.30-1.1 (Debian)
   2 GB RAM
   1 core QEMU Virtual CPU version 1.0 - cpu MHz: 3400.020

Workstation B: 
   MySQL Version: 5.5.41-MariaDB-1ubuntu0.14.04.1
   14 GB RAM
   4 cores Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz - cpu MHz: 1600.000

การกำหนดค่า mysql / maria คือการกำหนดค่าหุ้น

ฉันเปลี่ยนเมื่อวานเป็น MariaDB บนเวิร์กสเตชันของฉัน - แต่ก่อนที่ MariaDB สถิติจะยิ่งแย่ลง

ฉันลบฐานข้อมูลทั้งหมดในเวิร์กสเตชันแล้ว - ไม่ต่างกัน

คำถามใหญ่คือ: ประสิทธิภาพจะเป็นปัจจัย 53 ช้าลงได้อย่างไร ฉันไม่สามารถทำงานได้เช่นนี้ :-(

คำสั่งนำเข้าของฉัน:

pv sql/master.sql | mysql -h'localhost' -u'root' -p'root' 'master'

iostat -xm 5

เซิร์ฟเวอร์ A:

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
      17,43    0,00   30,28   51,85    0,00    0,44

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00   254,03    0,00 1305,45     0,00     6,09     9,56     0,78    0,60    0,00    0,60   0,57  74,25

เวิร์กสเตชัน B:

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
       7,32    0,00    3,22    5,03    0,00   84,42

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0,00     1,40    0,80  172,40     0,00     0,56     6,72     1,17    6,75   12,00    6,72   5,40  93,52

dd if=/dev/zero of=tempfile bs=1M count=1024 conv=fdatasync,notrunc

เซิร์ฟเวอร์ A:

1073741824 bytes (1,1 GB) copied, 18,6947 s, 57,4 MB/s

เวิร์กสเตชัน B:

1073741824 bytes (1,1 GB) copied, 8,95646 s, 120 MB/s

คุณช่วยอธิบายฉันว่าคุณต้องการนำเข้าฐานข้อมูลได้อย่างไร? (คำสั่ง mysql ที่เป็นรูปธรรมของคุณคืออะไร) "แสดงรายการกระบวนการอะไร" พูด? คุณได้ดูแล้วว่ากระบวนการทำงานเป็นรูปธรรมด้วย strace หรือไม่? คุณช่วยดูหน่อยได้ไหมว่าเครื่องของคุณกำลังแลกเปลี่ยน

ฉันแก้ไขคำถามของฉัน
อเล็กซ์

InnoDB? มูลค่าของinnodb_buffer_pool_sizeแต่ละเครื่องเป็นอย่างไร?
Rick James

คำตอบ:


47

คำตอบนี้เร่งทุกอย่างมากขึ้น:

/programming//a/2167641/292408

ฉันแค่

SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;

ที่จุดเริ่มต้นและ

COMMIT;
SET unique_checks=1;
SET foreign_key_checks=1;

ในตอนท้าย

ตอนนี้ใช้เวลา 3 นาที

(ความอนุเคราะห์ของ @andreasemer ผ่านทาง Twitter)


เทคนิคที่ยอดเยี่ยม สิ่งที่ฉันต้องรู้มีผลข้างเคียงของการทำเช่นนี้หรือไม่?
ธรรมะ Saputra

1
ในกรณีที่ข้อมูลของคุณเสียหายข้อ จำกัด ที่สำคัญต่างประเทศอาจไม่เป็นไปตามการนำเข้า
อเล็กซ์

เยี่ยมมาก ๆ คุณช่วยฉันชั่วโมงอย่างแท้จริง
Jafo

ไม่เร่งความเร็วในการแสดงสำหรับฉัน หากไม่มีสิ่งนี้มันก็เป็น 23 นาทีและหลังจากนั้นก็เป็น 23 นาที (ไฟล์ 3GB .sql)
Joshua Pinter

5

เติมเต็มสิ่งที่ฉันเห็นด้านบน ... ฉันมีไฟล์ดัมพ์ของฉันที่สร้างขึ้นโดยอัตโนมัติโดยสิ่งที่ชอบ:

mysqldump my_db > db-dump-file.sql

ฉันต้องการทำให้การนำเข้านี้เป็นแบบอัตโนมัติดังนั้นฉันจึงสร้างไฟล์สองไฟล์ในคอมพิวเตอร์ของฉันที่เรียกว่าdefault-start-import.sqlและdefault-end-import.sqlเนื้อหาของไฟล์เหล่านั้นคือdefault-start-import.sql :

SET autocommit=0;

และdefault-end-import.sql :

COMMIT;
SET autocommit=1;

และสคริปต์ที่ฉันเรียกใช้ก็เป็นอย่างนี้

cat default-start-import.sql db-dump-file.sql default-end-import.sql | mysql my_other_db

คำสั่งเดียวกัน แต่อ่านง่ายกว่า:

cat default-start-import.sql \
    db-dump-file.sql \
    default-end-import.sql \
| mysql my_other_db

ในกรณีcatนี้ใช้เพื่อเชื่อมไฟล์เหล่านั้นก่อนที่จะส่งไปยังไพพ์ ฉันคิดว่ามันเป็นสิ่งสำคัญที่ไฟล์ทั้งหมดลงท้ายด้วยอักขระขึ้นบรรทัดใหม่ (บรรทัดว่างท้ายไฟล์ถ้าเห็นจากเท็กซ์เอดิเตอร์) เพื่อให้catคำสั่งไม่รวมบรรทัดระหว่างไฟล์

การนำเข้าใช้งานได้ดีฉันไม่ได้ทดสอบว่าจริงเร็วขึ้นเพราะการปรับปรุงสิ่งที่เปิดใช้งานและปิดการใช้งานอัตโนมัติ แต่ถ้าสิ่งที่ทำให้เร็วขึ้นแล้วขั้นตอนพิเศษนี้ทำให้สิ่งต่าง ๆ ง่ายขึ้น


1

ฉันได้พยายาม --compressเช่นเดียวกับSET autocommit=0;เขาและพวกเขาช่วยในปริมาณที่น้อย แต่ ...

ฉันพบว่าการแปลงหลายรายการ INSERT INTO ...คำสั่งให้เป็นคำสั่งขนาดใหญ่หนึ่งคำพร้อมด้วยVALUES(...), (...)ความเร็วที่เพิ่มขึ้นหลายรายการอย่างมาก

ฉันกำลังใช้ mysql SSL ผ่าน WAN ฐานข้อมูล MySQL ระยะไกลโฮสต์บน Amazon

ด้วย 9 คอลัมน์และ 2,100 แถว:

  • แยก 2,100 INSERTข้อความ : 82s
  • 2 งบการเงินรวม INSERT : <1 วินาที

ด้วย 7 คอลัมน์และ 42,000 แถว:

  • แยก 42,000 INSERTงบข้อความ: 1,740s
  • 42 งบการเงินรวม INSERT : 105 วินาที

ดังนั้นขึ้นอยู่กับเครื่องมือสร้างการถ่ายโอนข้อมูลฐานข้อมูล (หรือเฉพาะรูปแบบของ INSERTข้อความสั่ง) ความเร็วจะได้รับผลกระทบ

หมายเหตุ:นี่จะเป็นการลด.sqlไฟล์ดัมพ์ลงมากกว่า 60% ในการทดสอบของฉันดังนั้นมันจะประหยัดใน i / o เช่นกัน

คำเตือน:มีข้อ จำกัด ทางกายภาพสำหรับเทคนิคนี้ด้วยmysqlและสำหรับผู้ที่ต้องการพกพา ... SQL Server ดูเหมือนจะ จำกัด เพียง 1,000 แถวเท่านั้นต่อครั้ง

ถึงกระนั้นการทำ 1,000 ครั้งต่อครั้งสำหรับ 42,000 แถวยังคงให้ผลดีขึ้น 1,657%!

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