ประสิทธิภาพการนำเข้า InnoDB


10

ฉันกำลังดิ้นรนกับการนำเข้าจำนวนมาก InnoDB- ตารางที่มีขนาดประมาณ 10 ล้านแถว (หรือ 7GB) (ซึ่งสำหรับฉันเป็นตารางที่ใหญ่ที่สุดที่ฉันเคยทำงานด้วย)

ฉันค้นคว้าวิธีปรับปรุงความเร็วการนำเข้าของ Inno และในขณะที่การติดตั้งของฉันมีลักษณะดังนี้:

/etc/mysql/my.cnf/
[...]
innodb_buffer_pool_size = 7446915072 # ~90% of memory
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000
innodb_thread_concurrency=0
innodb_doublewrite = 0
innodb_log_file_size = 1G
log-bin = ""
innodb_autoinc_lock_mode = 2
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_instances=8


import is done via bash script, here is the mysql code:
SET GLOBAL sync_binlog = 1;
SET sql_log_bin = 0;
SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET AUTOCOMMIT = 0;
SET SESSION tx_isolation='READ-UNCOMMITTED';
LOAD DATA LOCAL INFILE '$filepath' INTO TABLE monster
COMMIT;

ข้อมูลมีให้ในCSVไฟล์
ขณะนี้ฉันทดสอบการตั้งค่าด้วย 'การทดสอบทิ้ง' ที่เล็กลงด้วย 2 ล้าน 3 ล้าน…แถวแต่ละแถวและใช้time import_script.shเพื่อเปรียบเทียบประสิทธิภาพ

ข้อเสียเปรียบคือฉันได้รับเวลาโดยรวมเท่านั้นดังนั้นฉันจึงรอให้การนำเข้าทั้งหมดเสร็จสิ้นเพื่อรับผลลัพธ์

ผลลัพธ์ของฉันจนถึงปัจจุบัน:

  • 10,000 แถว: <1 วินาที
  • 100,000 แถว: 10 วินาที
  • 300,000 แถว: 40 วินาที
  • 2 ล้านแถว: 18 นาที
  • 3 ล้านแถว: 26 นาที
  • 4 ล้านแถว: (ยกเลิกหลังจาก 2 ชั่วโมง)

ดูเหมือนว่าจะไม่มีวิธีแก้ปัญหา 'ตำราอาหาร' และเราต้องหาวิธีการผสมผสานที่ดีที่สุดของการตั้งค่าด้วยตนเอง
นอกจากข้อเสนอแนะเกี่ยวกับสิ่งที่จะเปลี่ยนแปลงในการตั้งค่าของฉันฉันก็จะขอบคุณข้อมูลมากขึ้นว่าฉันสามารถเปรียบเทียบกระบวนการนำเข้า / รับข้อมูลเชิงลึกมากขึ้นเกี่ยวกับสิ่งที่เกิดขึ้นและที่คอขวดได้
ฉันพยายามอ่านเอกสารประกอบสำหรับการตั้งค่าที่ฉันเปลี่ยน แต่อีกครั้งฉันไม่ทราบถึงผลข้างเคียงใด ๆ และถ้าฉันอาจลดประสิทธิภาพด้วยค่าที่เลือกไม่ดี

ในขณะนี้ฉันต้องการลองใช้ข้อเสนอแนะจากการแชทเพื่อใช้MyISAMระหว่างการนำเข้าและเปลี่ยนเครื่องมือตารางหลังจากนั้น
ฉันต้องการลองสิ่งนี้ แต่ในขณะนี้DROP TABLEแบบสอบถามของฉันก็ใช้เวลาหลายชั่วโมงกว่าจะเสร็จ (ซึ่งดูเหมือนว่าตัวบ่งชี้อื่นการตั้งค่าของฉันนั้นน้อยที่สุดแล้ว)

ข้อมูลเพิ่มเติม:
เครื่องที่ฉันใช้อยู่ในปัจจุบันมี RAM 8GB และฮาร์ดไดรฟ์ Solid State Hybrid w / 5400RPM
ในขณะที่เราตั้งเป้าหมายที่จะลบข้อมูลที่ล้าสมัยออกจากตารางในคำถามฉันยังคงต้องการนำเข้าค่อนข้างรวดเร็วใน
การทดสอบ a) automatic data cleanup featureขณะที่กำลังพัฒนาและ
b) ในกรณีที่เซิร์ฟเวอร์ของเราเกิดปัญหาเราต้องการใช้เซิร์ฟเวอร์ตัวที่สองของเราแทน ข้อมูลที่เป็นปัจจุบันการนำเข้าครั้งล่าสุดใช้เวลามากกว่า 24 ชั่วโมง)

mysql> SHOW CREATE TABLE monster\G
*************************** 1. row ***************************
       Table: monster
Create Table: CREATE TABLE `monster` (
  `monster_id` int(11) NOT NULL AUTO_INCREMENT,
  `ext_monster_id` int(11) NOT NULL DEFAULT '0',
  `some_id` int(11) NOT NULL DEFAULT '0',
  `email` varchar(250) NOT NULL,
  `name` varchar(100) NOT NULL,
  `address` varchar(100) NOT NULL,
  `postcode` varchar(20) NOT NULL,
  `city` varchar(100) NOT NULL,
  `country` int(11) NOT NULL DEFAULT '0',
  `address_hash` varchar(250) NOT NULL,
  `lon` float(10,6) NOT NULL,
  `lat` float(10,6) NOT NULL,
  `ip_address` varchar(40) NOT NULL,
  `cookie` int(11) NOT NULL DEFAULT '0',
  `party_id` int(11) NOT NULL,
  `status` int(11) NOT NULL DEFAULT '2',
  `creation_date` datetime NOT NULL,
  `someflag` tinyint(1) NOT NULL DEFAULT '0',
  `someflag2` tinyint(4) NOT NULL,
  `upload_id` int(11) NOT NULL DEFAULT '0',
  `news1` tinyint(4) NOT NULL DEFAULT '0',
  `news2` tinyint(4) NOT NULL,
  `someother_id` int(11) NOT NULL DEFAULT '0',
  `note` varchar(2500) NOT NULL,
  `referer` text NOT NULL,
  `subscription` int(11) DEFAULT '0',
  `hash` varchar(32) DEFAULT NULL,
  `thumbs1` int(11) NOT NULL DEFAULT '0',
  `thumbs2` int(11) NOT NULL DEFAULT '0',
  `thumbs3` int(11) NOT NULL DEFAULT '0',
  `neighbours` tinyint(4) NOT NULL DEFAULT '0',
  `relevance` int(11) NOT NULL,
  PRIMARY KEY (`monster_id`),
  KEY `party_id` (`party_id`),
  KEY `creation_date` (`creation_date`),
  KEY `email` (`email`(4)),
  KEY `hash` (`hash`(8)),
  KEY `address_hash` (`address_hash`(8)),
  KEY `thumbs3` (`thumbs3`),
  KEY `ext_monster_id` (`ext_monster_id`),
  KEY `status` (`status`),
  KEY `note` (`note`(4)),
  KEY `postcode` (`postcode`),
  KEY `some_id` (`some_id`),
  KEY `cookie` (`cookie`),
  KEY `party_id_2` (`party_id`,`status`)
) ENGINE=InnoDB AUTO_INCREMENT=13763891 DEFAULT CHARSET=utf8

2
คุณลองนำเข้าจำนวนมากน้อยลงเช่นแถว 10K หรือ 100K หรือไม่
ypercubeᵀᴹ

1
โปรดเรียกใช้SHOW CREATE TABLE yourtable\Gเพื่อแสดงโครงสร้างตารางของตาราง 10 ล้านแถวนี้
RolandoMySQLDBA

@RolandoMySQLDBA ดังนั้นฉันจึง (ด้วยชื่อฟิลด์ที่บดบัง)
nuala

โดยการปิดการใช้งานบัฟเฟอร์การเขียนคู่ ( innodb_doublewrite = 0) การติดตั้ง MySQL ของคุณจะไม่ผิดพลาดอย่างปลอดภัย: หากคุณมีปัญหาไฟฟ้าขัดข้อง (ไม่ใช่ความผิดพลาดของ MySQL) ข้อมูลของคุณอาจเสียหายอย่างเงียบ ๆ
jfg956

คำตอบ:


13

ก่อนอื่นคุณต้องรู้ว่าคุณกำลังทำอะไรกับ InnoDB เมื่อคุณทำการไถแถวเป็นล้าน ๆ แถวเข้าไปในตาราง InnoDB ลองดูที่สถาปัตยกรรม InnoDB

สถาปัตยกรรม InnoDB

ที่มุมซ้ายบนมีภาพประกอบของ InnoDB Buffer Pool ขอให้สังเกตว่ามีส่วนหนึ่งของมันที่ทุ่มเทให้กับการแทรกบัฟเฟอร์ มันทำอะไร มันมีไว้เพื่อโอนย้ายการเปลี่ยนแปลงไปยังดัชนีรองจากบัฟเฟอร์พูลไปยังแทรกบัฟเฟอร์ภายในตารางระบบ (aka ibdata1) โดยค่าเริ่มต้นinnodb_change_buffer_max_sizeถูกตั้งค่าเป็น 25 ซึ่งหมายความว่าบัฟเฟอร์บัฟเฟอร์สูงสุด 25% สามารถใช้สำหรับการประมวลผลดัชนีรองได้

ในกรณีของคุณคุณมี 6.935 GB สำหรับ InnoDB Buffer Pool สูงสุด 1.734 GB จะใช้สำหรับการประมวลผลดัชนีรองของคุณ

ตอนนี้ดูที่โต๊ะของคุณ คุณมีดัชนีรอง 13 รายการ แต่ละแถวที่คุณดำเนินการจะต้องสร้างรายการดัชนีรองจับคู่กับคีย์หลักของแถวและส่งเป็นคู่จาก Insert Buffer ใน Buffer Pool ลงใน Insert Buffer ใน ibdata1 ที่เกิดขึ้น 13 ครั้งกับแต่ละแถว ทวีคูณโดย 10 ล้านและคุณจะรู้สึกได้ถึงคอขวด

อย่าลืมว่าการนำเข้า 10 ล้านแถวในการทำธุรกรรมเดียวจะทำให้ทุกอย่างกลายเป็นเซ็กเมนต์ย้อนกลับเดียวและเติมพื้นที่ UNDO ใน ibdata1

คำแนะนำ

คำแนะนำ # 1

คำแนะนำแรกของฉันสำหรับการนำเข้าตารางนี้ค่อนข้างใหญ่จะเป็น

  • ดร็อปดัชนีที่ไม่ซ้ำทั้งหมด
  • นำเข้าข้อมูล
  • สร้างดัชนีที่ไม่ซ้ำกันทั้งหมด

คำแนะนำ # 2

กำจัดดัชนีที่ซ้ำกัน ในกรณีของคุณคุณมี

KEY `party_id` (`party_id`),
KEY `party_id_2` (`party_id`,`status`)

ดัชนีทั้งสองเริ่มต้นด้วยparty_idคุณสามารถเพิ่มการประมวลผลดัชนีรองได้อย่างน้อย 7.6% กำจัดดัชนีหนึ่งจาก 13 คุณต้องเรียกใช้ในที่สุด

ALTER TABLE monster DROP INDEX party_id;

คำแนะนำ # 3

กำจัดดัชนีที่คุณไม่ได้ใช้ ดูรหัสแอปพลิเคชันของคุณและดูว่าข้อความค้นหาของคุณใช้ดัชนีทั้งหมดหรือไม่ คุณอาจต้องการศึกษาการใช้ดัชนี ptเพื่อให้มันแนะนำว่าดัชนีใดไม่ได้ถูกใช้

คำแนะนำ # 4

คุณควรเพิ่มinnodb_log_buffer_sizeเป็น 64M เนื่องจากค่าเริ่มต้นคือ 8M บัฟเฟอร์การบันทึกที่ใหญ่กว่าอาจเพิ่มประสิทธิภาพการเขียน I / O ของ InnoDB

บทส่งท้าย

วางคำแนะนำสองข้อแรกเข้าที่ให้ทำดังนี้:

  • ดร็อปดัชนีที่ไม่ซ้ำกัน 13 รายการ
  • นำเข้าข้อมูล
  • สร้างดัชนีที่ไม่ซ้ำกันทั้งหมดยกเว้นparty_idดัชนี

บางทีสิ่งต่อไปนี้อาจช่วยได้

CREATE TABLE monster_new LIKE monster;
ALTER TABLE monster_new
  DROP INDEX `party_id`,
  DROP INDEX `creation_date`,
  DROP INDEX `email`,
  DROP INDEX `hash`,
  DROP INDEX `address_hash`,
  DROP INDEX `thumbs3`,
  DROP INDEX `ext_monster_id`,
  DROP INDEX `status`,
  DROP INDEX `note`,
  DROP INDEX `postcode`,
  DROP INDEX `some_id`,
  DROP INDEX `cookie`,
  DROP INDEX `party_id_2`;
ALTER TABLE monster RENAME monster_old;
ALTER TABLE monster_new RENAME monster;

monsterนำเข้าข้อมูลลง จากนั้นเรียกใช้สิ่งนี้

ALTER TABLE monster
  ADD INDEX `creation_date`,
  ADD INDEX `email` (`email`(4)),
  ADD INDEX `hash` (`hash`(8)),
  ADD INDEX `address_hash` (`address_hash`(8)),
  ADD INDEX `thumbs3` (`thumbs3`),
  ADD INDEX `ext_monster_id` (`ext_monster_id`),
  ADD INDEX `status` (`status`),
  ADD INDEX `note` (`note`(4)),
  ADD INDEX `postcode` (`postcode`),
  ADD INDEX `some_id` (`some_id`),
  ADD INDEX `cookie` (`cookie`),
  ADD INDEX `party_id_2` (`party_id`,`status`);

ให้มันลอง !!!

ALTERNATIVE

คุณสามารถสร้างตารางที่เรียกว่าmonster_csvเป็นตาราง MyISAM โดยไม่มีดัชนีและทำสิ่งนี้:

CREATE TABLE monster_csv ENGINE=MyISAM AS SELECT * FROM monster WHERE 1=2;
ALTER TABLE monster RENAME monster_old;
CREATE TABLE monster LIKE monster_old;
ALTER TABLE monster DROP INDEX `party_id`;

monster_csvนำเข้าข้อมูลของคุณลงใน จากนั้นใช้ mysqldump เพื่อสร้างการนำเข้าอื่น

mysqldump -t -uroot -p mydb monster_csv | sed 's/monster_csv/monster/g' > data.sql

ไฟล์ mysqldump data.sqlจะขยายคำสั่ง INSERT เพื่อนำเข้าแถวละ 10,000-20,000 แถว

ตอนนี้เพียงโหลด mysqldump

mysql -uroot -p mydb < data.sql

ในที่สุดกำจัดตาราง MyISAM

DROP TABLE monster_csv;

ฉันไม่ได้ตระหนักถึงกุญแจเหล่านั้นทั้งหมด (มันไม่ใช่การออกแบบของฉัน) แต่คำอธิบายของคุณดูน่าเชื่อถือมาก สำหรับวันนี้การเริ่มต้นอีกครั้งก็ล่าช้า แต่ฉันเห็นคำแนะนำที่ดีว่าจะลองอะไรในวันพรุ่งนี้ จะแจ้งให้คุณทราบ! <3
nuala

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

8

ฉันต้องการเขียนความคิดเห็น (เพราะนี่ไม่ใช่คำตอบที่ชัดเจน) แต่มันยาวเกินไป:

ฉันจะให้คำแนะนำกว้าง ๆ กับคุณและเราสามารถบอกรายละเอียดของแต่ละเรื่องได้หากคุณต้องการ:

  • ลดความทนทาน (คุณได้ทำไปแล้วบางส่วน) เวอร์ชันล่าสุดอนุญาตให้ทำได้มากกว่าเดิม คุณสามารถปิดการใช้งานบัฟเฟอร์การเขียนซ้ำได้เนื่องจากความเสียหายไม่ใช่ปัญหาสำหรับการนำเข้า
  • เพิ่มการบัฟเฟอร์โดย: เพิ่มขนาดบันทึกธุรกรรมและเพิ่มขนาดบัฟเฟอร์พูลที่พร้อมใช้งาน ตรวจสอบการใช้ไฟล์บันทึกการทำธุรกรรมและจุดตรวจสอบ อย่ากลัวไฟล์บันทึกขนาดใหญ่สำหรับการนำเข้า
  • หลีกเลี่ยงการทำธุรกรรมจำนวนมาก - การย้อนกลับของคุณจะเต็มไปด้วยข้อมูลที่ไม่จำเป็น นี่อาจเป็นปัญหาใหญ่ที่สุดของคุณ
  • SQL จะเป็นคอขวดให้หลีกเลี่ยงโอเวอร์เฮดของ SQL (ตัวจัดการไฟล์, memcached) และ / หรือโหลดพร้อมกันในหลาย ๆ เธรดพร้อมกัน การเห็นพ้องต้องกันถึงจุดที่น่าสนใจไม่มากเกินไปไม่น้อยเกินไป
  • โหลดข้อมูลในการกระจายตัวของคำสั่งซื้อหลักอาจเป็น isse
  • ทดสอบการบีบอัด InnoDB หาก IO เป็นคอขวดของคุณและ CPU และหน่วยความจำจะไม่ทำให้ช้าลง
  • ลองสร้างแป้นรองของคุณหลังจากนั้น (เร็วกว่าในบางกรณี) ไม่โหลดการจัดทำดัชนี DATA- แป้นปิดการใช้งานไม่ได้ส่งผลกระทบต่อ InnoDB หากไม่ใช่ให้ตรวจสอบบัฟเฟอร์การแทรกของคุณ (อาจแซงครึ่งหนึ่งของพูลบัฟเฟอร์ของคุณ)
  • เปลี่ยนหรือปิดใช้งานอัลกอริทึมการตรวจสอบ - ไม่ใช่ปัญหาของคุณ แต่มันจะกลายเป็นปัญหาคอขวดของการ์ดแฟลชระดับไฮเอนด์
  • วิธีสุดท้าย: ตรวจสอบเซิร์ฟเวอร์ของคุณเพื่อค้นหาคอขวดปัจจุบันของคุณและพยายามบรรเทา (InnoDB ยืดหยุ่นมากเกี่ยวกับเรื่องนั้น)

โปรดจำไว้ว่าสิ่งเหล่านี้บางอย่างไม่ปลอดภัยหรือไม่แนะนำให้นำเข้าที่ไม่ใช่การนำเข้า (การทำงานปกติ)


ขอบคุณมาก! ฉันชอบที่จะลองความคิดของ Rolandoเกี่ยวกับดัชนีก่อน แต่ฉันเดาว่าสิ่งนี้ "การทำรายการย้อนกลับ" จะยังคงเป็นปัญหาอยู่ คุณช่วยอธิบายเรื่องนี้ได้ไหม? ฉันคิดว่าฉันต้องการที่จะปิดการใช้งานเท่าของการทำงานนี้เป็นไปได้ในระหว่างการนำเข้าและเพิ่งเปิดใช้งานเมื่อจะเข้าสู่การผลิต ~ ผมคิดว่า ...
Nuala

1
ข้อเสนอแนะของ Rolando คือประเด็นของฉัน # 7 การหลีกเลี่ยงค่าใช้จ่ายในการย้อนกลับนั้นง่ายเหมือนการรวมกันของSET SESSION tx_isolation='READ-UNCOMMITTED';(มีประโยชน์เฉพาะในกรณีที่คุณนำเข้าหลายกระทู้พร้อมกัน) และความคิดเห็น @ypercube เกี่ยวกับการแทรกเป็นชุด คุณมีตัวอย่างเต็มรูปแบบได้ที่นี่: mysqlperformanceblog.com/2008/07/03/…ตรวจสอบให้แน่ใจว่าคุณได้รับประโยชน์จากคุณสมบัติทั้งหมดใน InnoDB เวอร์ชันล่าสุด: mysqlperformanceblog.com/2011/01/07/ …
jynus

1
ฉันมีความประทับใจทั่วไปที่จะหลีกเลี่ยงการนำเข้าใน chucks ขนาดเล็ก แต่แทนที่จะไปสำหรับการดำเนินการ "รวมทั้งหมด" แต่ฉันเห็นหลายเธรดสามารถเปิดโอกาสบางอย่าง เดาว่าเฉพาะกรณีมาก อย่างไรก็ตามฉันยอมรับคำตอบของ Rolando เนื่องจากการปรับแต่ง (# 7 ของคุณ) เพียงอย่างเดียวช่วยให้ฉันได้รับการนำเข้าเต็มรูปแบบใน <1 ชั่วโมง แต่รายการของคุณอยู่ไกลจากไร้ค่าแน่นอนและฉันเดาว่าจะใช้เพื่อการอ้างอิงในไม่ช้า กลัวฉัน :)
nuala

ฉันเห็นด้วยกับ @yoshi คำตอบของคุณครอบคลุมมากขึ้นในแง่ของการแก้ไขปัญหาและการปรับปรุงประสิทธิภาพ +1
RolandoMySQLDBA

3

เคล็ดลับที่ดีส่วนใหญ่ได้รับมาแล้ว แต่ยังไม่มีคำอธิบายมากมายสำหรับสิ่งที่ดีที่สุด ฉันจะให้รายละเอียดเพิ่มเติม

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

ไฟล์บันทึกของ InnoDB ที่ใหญ่ขึ้นจะช่วยคุณได้มาก (ถ้าคุณใช้ MySQL 5.6 เพราะมันเป็นไปไม่ได้ที่จะเพิ่มใน MySQL 5.5) คุณกำลังแทรกข้อมูล 7 GB ฉันขอแนะนำขนาดบันทึกทั้งหมดอย่างน้อย 8 GB (เก็บไว้innodb_log_files_in_groupที่ค่าเริ่มต้น (2) และชนinnodb_log_file_sizeที่ 4 GB) 8 GB นี้ไม่ถูกต้อง: อย่างน้อยควรมีขนาดการนำเข้าในบันทึก REDO และอาจเป็นสองเท่าหรือสี่เท่าของขนาดนั้น เหตุผลที่อยู่เบื้องหลังขนาดบันทึกของ InnoDB จะเพิ่มขึ้นเมื่อบันทึกเกือบเต็ม InnoDB จะเริ่มล้างบัฟเฟอร์พูลไปยังดิสก์อย่างจริงจังเพื่อหลีกเลี่ยงการบันทึกการเติม (เมื่อบันทึกเต็ม InnoDB จะไม่สามารถเขียนฐานข้อมูลใด ๆ จนกว่าจะถึงเวลา หน้าของพูลบัฟเฟอร์ถูกเขียนลงดิสก์)

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

คุณมีบัฟเฟอร์พูลขนาดใหญ่เท่ากับ RAM ของคุณและถ้าตารางของคุณไม่พอดีก็ไม่มีอะไรที่คุณสามารถทำได้ยกเว้นการซื้อ RAM เพิ่ม แต่ตารางคุณพอดีกับบัฟเฟอร์พูล แต่ใหญ่กว่า 75% ของบัฟเฟอร์พูลคุณอาจลองเพิ่มinnodb_max_dirty_pages_pctเป็น 85 หรือ 95 ในระหว่างการนำเข้า (ค่าเริ่มต้นคือ 75) พารามิเตอร์การกำหนดค่านี้จะบอก InnoDB ให้เริ่มล้างข้อมูลพูลบัฟเฟอร์อย่างจริงจังเมื่อเปอร์เซ็นต์ของเพจสกปรกถึงขีด จำกัด นี้ โดยการชนพารามิเตอร์นี้ (และหากคุณโชคดีกับขนาดข้อมูล) คุณอาจหลีกเลี่ยง IO ที่ก้าวร้าวในระหว่างการนำเข้าของคุณและทำให้ IO เหล่านั้นเลื่อนออกไปในภายหลัง

อาจจะ (และนี่คือการเดา) การนำเข้าข้อมูลของคุณในการทำธุรกรรมขนาดเล็กจำนวนมากจะช่วยคุณ ฉันไม่ทราบวิธีการสร้างบันทึก REDO อย่างแน่นอน แต่ถ้าบัฟเฟอร์ใน RAM (และดิสก์เมื่อต้องการ RAM มากเกินไป) ในขณะที่ธุรกรรมกำลังดำเนินการคุณอาจจบลงด้วย IOs ที่ไม่จำเป็น คุณสามารถลองทำสิ่งนี้: เมื่อไฟล์ของคุณถูกจัดเรียงให้แยกเป็นชิ้น ๆ (ลองด้วยขนาด 16 MB และขนาดอื่น ๆ ) แล้วนำเข้าทีละไฟล์ สิ่งนี้จะช่วยให้คุณสามารถควบคุมความคืบหน้าของการนำเข้าของคุณ หากคุณไม่ต้องการให้ผู้อ่านอื่นมองเห็นข้อมูลของคุณบางส่วนในขณะที่คุณนำเข้าคุณสามารถนำเข้าโดยใช้ชื่อตารางอื่นสร้างดัชนีในภายหลังและเปลี่ยนชื่อตาราง

เกี่ยวกับดิสก์ไฮบริด SSD / 5400RPM ของคุณฉันไม่รู้เกี่ยวกับสิ่งเหล่านั้นและวิธีเพิ่มประสิทธิภาพนี้ 5400RPM ดูช้าสำหรับฐานข้อมูล แต่บางที SSD อาจหลีกเลี่ยงปัญหานั้นได้ อาจเป็นเพราะคุณกำลังเติมส่วน SSD ของดิสก์ของคุณด้วยการเขียนตามลำดับลงในบันทึก REDO และ SSD กำลังรบกวนการทำงาน ฉันไม่รู้.

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

หากคุณกำลังพิจารณาหลายเธรดบางทีคุณอาจมีคอมพิวเตอร์หลายซ็อกเก็ต (NUMA) ในกรณีนี้ให้แน่ใจว่าคุณหลีกเลี่ยงปัญหาความบ้าแลกเปลี่ยน MySQL

หากคุณใช้ MySQL 5.5 ให้อัปเกรดเป็น MySQL 5.6: มีตัวเลือกในการเพิ่มขนาดล็อกบันทึกและมีอัลกอริทึมการล้างบัฟเฟอร์พูลที่ดีกว่า

ขอให้โชคดีกับการนำเข้าของคุณ

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