ขณะนี้ฉันกำลังทดสอบ TokuDB และรู้สึกประทับใจมาก ในขณะนี้ เม็ดมีดต่อวินาทีพุ่งสูงสุดที่เพียง 50,000 ต่อวินาที โดยทำงานสองงานพร้อมกัน อัตราการแทรกเฉลี่ยอยู่ระหว่าง 38,000 ถึง 42,000 เม็ดต่อวินาที
ฉันต้องการที่จะเพิ่มการแทรก 100,000 ต่อวินาทีให้สูงขึ้น เนื่องจากฉันจะต้องแทรกแถวที่คำนวณแล้ว 1.2 พันล้านแถวในตอนนี้และอีกประมาณ 6 พันล้านแถวในอนาคตอันใกล้นี้ ฉันต้องการคำแนะนำเกี่ยวกับวิธีการบรรลุเป้าหมายนี้ :-)
การตั้งค่าปัจจุบันของฉัน:
- ฮาร์ดแวร์: VPS พร้อม RAM 4GB, 150GB SSD, 2 คอร์: Intel Westmere E56xx/L56xx/X56xx (Nehalem-C) CPU 2.59GHz
- ตัวเลือกการเมานต์ดิสก์: ค่าเริ่มต้น, noatime
- ระบบปฏิบัติการ: CentOS 6.8 64bit
- ฐานข้อมูล: เซิร์ฟเวอร์ Percona 5.7.14-8
การตั้งค่า My.cnf:
# TokuDB #
tokudb_cache_size = 2G
tokudb_commit_sync = 0
tokudb_fsync_log_period = 1000
เค้าโครงตาราง TokuDB:
CREATE TABLE `t1` (
`id` int(15) NOT NULL AUTO_INCREMENT,
`m_id` int(11) NOT NULL,
`c1` decimal(6,2) DEFAULT NULL,
`c2` decimal(6,2) DEFAULT NULL,
`c3` decimal(6,2) DEFAULT NULL,
`c4` decimal(6,2) DEFAULT NULL,
`c5` decimal(6,2) DEFAULT NULL,
`c6` decimal(6,2) DEFAULT NULL,
`c7` decimal(6,2) DEFAULT NULL,
`factor` decimal(4,2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=TokuDB DEFAULT CHARSET=latin1
CREATE TABLE `t2` (
`id` int(15) NOT NULL AUTO_INCREMENT,
`v_id` int(15) NOT NULL,
`pid` int(11) DEFAULT NULL,
`amount` decimal(6,2) DEFAULT NULL,
`unit` int(1) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=TokuDB DEFAULT CHARSET=latin1
ฉันตระหนักถึงความจริงที่ว่าฉันไม่ได้ใช้ดัชนีใด ๆ นอกเหนือจากดัชนีคีย์หลัก นี่เป็นเพราะผลกระทบด้านลบที่คีย์จะมีต่อการใส่ คีย์คลัสเตอร์สำหรับแต่ละตารางจะถูกสร้างขึ้นเมื่อสิ้นสุดงานแทรก
ตัวเลือกบรรทัดคำสั่ง MySQL เพิ่มเติม:
SET unique_checks=OFF;
อย่างไรก็ตาม ฉันไม่สามารถรับสิ่งนี้ได้ใน my.cnf.. หากมีใครรู้ว่าทำอย่างไร สิ่งนี้จะได้รับการชื่นชมอย่างมาก (ในปัจจุบัน Unique_checks = off จะบล็อก MySQL ไม่ให้เริ่มทำงานเนื่องจากตัวแปรที่ไม่รู้จักใน my.cnf) .
คำสั่ง SQL ถูกจัดกลุ่มเป็นกลุ่มละ 15.000 สคริปต์ PHP สร้างคำสั่ง SQL และส่งแบบสอบถามผ่าน mysqli_multiquery ไปยังเซิร์ฟเวอร์ MySQL:
<?PHP
foreach (generateCombinations($Arr) as $c) {
$QueryBatch[] = "insert into t1 values (NULL"
. ", " . $record->id
. ", " . rand(1, 35)
. ", " . rand(1, 140)
. ", " . rand(1, 20)
. ", NULL"
. ", " . rand(1, 14)
. ", " . rand(1, 300)
. ", " . rand(1, 4)
. ", NULL );";
$QueryBatch[] = "SET @t1id = LAST_INSERT_ID();";
$cntBatch++;
$pquery = array();
foreach ( $c as $key => $pid){
if ( is_null($pid) )
continue;
$pquery[] = "(NULL, @t1id, " . $pid . ", " . rand(1, 800) . ", 0)";
$cntBatch++;
}
$QueryBatch[] = "insert into t2 values " . implode(',', $pquery) . ";";
if ($cntBatch > 15000) {
$query = implode($QueryBatch);
if ( $mysqli->multi_query($query) ){
while ($mysqli->next_result()) {;}
} else {
printf("Errormessage: %s\n", $mysqli->error);
echo $query . "\n";
}
$cntBatch = 0;
unset($QueryBatch);
}
}
?>
ตัวอย่างของคำสั่งแทรก SQL:
insert into t1 values (NULL, 1 , 30, 100, 15, NULL, 10, 250, 2, NULL );
SET @t1id = LAST_INSERT_ID();
insert into t2 values (NULL, @t1id, 1, 750, 0),(NULL, @t1id, 1, 600, 0),(NULL, @t1id, 1, 500, 0),(NULL, @t1id, 1, 400, 0),(NULL, @t1id, 1, 300, 0),(NULL, @t1id, 1, 200, 0),(NULL, @t1id, 1, 100, 0);
insert into t1 values (NULL, 2 , 25, 95, 14, NULL, 11, 200, 3, NULL );
SET @t1id = LAST_INSERT_ID();
insert into t2 values (NULL, @t1id, 1, 600, 0),(NULL, @t1id, 1, 100, 0),(NULL, @t1id, 1, 300, 0),(NULL, @t1id, 1, 443, 0),(NULL, @t1id, 1, 521, 0),(NULL, @t1id, 1, 213, 0),(NULL, @t1id, 1, 433, 0);
[.. At least 14982 more..]