MySQL สามารถทำการสืบค้นบนพันล้านแถวได้หรือไม่?


283

ฉันกำลังวางแผนในการจัดเก็บสแกนจากแมสสเปคโตรมิเตอร์ในฐานข้อมูล MySQL และต้องการทราบว่าการจัดเก็บและวิเคราะห์ข้อมูลจำนวนนี้เป็นไปได้จากระยะไกลหรือไม่ ฉันรู้ว่าประสิทธิภาพอาจแตกต่างกันไปขึ้นอยู่กับสภาพแวดล้อม แต่ฉันกำลังมองหาลำดับความสำคัญอย่างคร่าวๆ: ข้อความค้นหาจะใช้เวลา 5 วันหรือ 5 มิลลิวินาทีหรือไม่

รูปแบบอินพุต

ไฟล์อินพุตแต่ละไฟล์มีสเปคโตรมิเตอร์วิ่งเดียว การทดสอบแต่ละครั้งประกอบด้วยชุดของการสแกนและการสแกนแต่ละครั้งจะมีชุดข้อมูลที่สั่งซื้อ มีข้อมูลเมตาเล็กน้อย แต่ส่วนใหญ่ของไฟล์ประกอบด้วยอาร์เรย์ int หรือ 32- หรือ 64- บิต

ระบบโฮสต์

| ---------------- + ------------------------------- |
| ระบบปฏิบัติการ | Windows 2008 64-bit |
| รุ่น MySQL 5.5.24 (x86_64) |
| ซีพียู | 2x Xeon E5420 (ทั้งหมด 8 คอร์)
| RAM | 8GB |
| ระบบไฟล์ SSD 500 GiB |
| HDD RAID | 12 TiB |
| ---------------- + ------------------------------- |

มีบริการอื่น ๆ ที่ใช้งานบนเซิร์ฟเวอร์โดยใช้เวลาตัวประมวลผลเล็กน้อย

สถิติไฟล์

| ------------------ + -------------- |
| จำนวนไฟล์ | ~ 16,000 |
| ขนาดทั้งหมด 1.3 TiB |
| ขนาดขั้นต่ำ 0 ไบต์ |
| ขนาดสูงสุด 12 GiB |
| หมายถึง | 800 MiB |
| ค่ามัธยฐาน | 500 MiB |
| ดาต้าพอยน์ทั้งหมด ~ 200 พันล้าน |
| ------------------ + -------------- |

จำนวนรวมของ datapoints เป็นมากประมาณการคร่าวๆ

สคีมาที่เสนอ

ฉันวางแผนในการทำสิ่งที่ "ถูกต้อง" (เช่น normalizing ข้อมูลอย่างบ้าคลั่ง) และอื่น ๆ จะมีrunsตารางเป็นspectraตารางที่มีคีย์ต่างประเทศเพื่อrunsและตารางที่มีคีย์ต่างประเทศเพื่อdatapointsspectra

คำถามดาต้าพอยน์ 200 พันล้าน

ฉันจะทำการวิเคราะห์ในสเปกตรัมหลาย ๆ ตัวและอาจเป็นหลาย ๆ วิ่งทำให้เกิดข้อความค้นหาที่สามารถสัมผัสแถวนับล้านได้ สมมติว่าฉันทำดัชนีทุกอย่างถูกต้อง (ซึ่งเป็นหัวข้อสำหรับคำถามอื่น) และไม่พยายามสับเปลี่ยน MiB นับร้อยผ่านเครือข่ายมันเป็นไปได้หรือไม่ที่ MySQL จะจัดการเรื่องนี้จากระยะไกล

ข้อมูลเพิ่มเติม

ข้อมูลการสแกนจะมาจากไฟล์ใน XML-based mzMLรูปแบบ เนื้อของรูปแบบนี้อยู่ใน <binaryDataArrayList>องค์ประกอบที่เก็บข้อมูล การสแกนแต่ละผลิต> = 2 <binaryDataArray>องค์ประกอบที่นำมารวมกันในรูปแบบ 2 มิติ (หรือมากกว่า) [[123.456, 234.567, ...], ...]อาร์เรย์ของฟอร์ม

ข้อมูลเหล่านี้เป็นแบบเขียนครั้งเดียวดังนั้นประสิทธิภาพการอัปเดตและความปลอดภัยของธุรกรรมจึงไม่เกี่ยวข้อง

แผนการที่ไร้เดียงสาของฉันสำหรับสคีมาฐานข้อมูลคือ:

runs โต๊ะ

| ชื่อคอลัมน์ | ประเภท |
| ------------- + ------------- |
| id | คีย์หลัก |
| start_time | TIMESTAMP |
| ชื่อ | VARCHAR |
| ------------- + ------------- |

spectra โต๊ะ

| ชื่อคอลัมน์ | ประเภท |
| ---------------- + ------------- |
| id | คีย์หลัก |
| ชื่อ | VARCHAR |
| ดัชนี | INT |
| สเปกตรัม | INT |
| การเป็นตัวแทน | INT |
| run_id | คีย์ต่างประเทศ
| ---------------- + ------------- |

datapoints โต๊ะ

| ชื่อคอลัมน์ | ประเภท |
| ------------- + ------------- |
| id | คีย์หลัก |
| สเปกตรัม | คีย์ต่างประเทศ
| mz | สองเท่า |
| num_counts | สองเท่า |
| ดัชนี | INT |
| ------------- + ------------- |

มันสมเหตุสมผลหรือไม่


ดังนั้นในขณะที่คุณสามารถอนุมานได้ฉันเป็นโปรแกรมเมอร์ไม่ใช่นักชีววิทยาในห้องปฏิบัติการดังนั้นฉันจึงไม่รู้วิทยาศาสตร์เกือบเท่านักวิทยาศาสตร์จริง ๆ

นี่คือพล็อตของสเปกตรัมเดียว (สแกน) ของประเภทของข้อมูลที่ฉันจะจัดการ:

สกรีนช็อตของ Viewer

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



8
เนื่องจากนี่เป็นข้อมูล A / D polling มวลสเปกโตรมิเตอร์จึงเป็นเรื่องที่น่าประหลาดใจที่เก็บไว้ในฐานข้อมูล ฉันจะใช้ข้อมูลดิบของฉันทิ้งมันประมวลผลและเก็บผลลัพธ์ที่ประมวลผลไว้ในฐานข้อมูล ผลลัพธ์จะเป็น (a) รูปแบบของคลื่นที่เก็บไว้หนึ่งรูปแบบของคลื่นต่อแถว (b) ข้อมูลอื่น ๆ ที่เกี่ยวข้องกับรูปแบบของคลื่นเช่นเส้นโค้งการปรับเทียบและ (c) แถวผลลัพธ์ในฐานข้อมูล สิ่งนี้จะลดจำนวนแถวของพันล้านออกไปจากการออกแบบ เมื่อคุณต้องการเรียกใช้การวิเคราะห์เริ่มต้นใหม่คุณจะแก้ไขพารามิเตอร์บางอย่างได้อย่างมีประสิทธิภาพเรียกใช้การคำนวณแบบยักษ์และจัดเก็บผลลัพธ์ใหม่ใน db
Warren P

คำตอบ:


115

ฉันไม่คุ้นเคยกับความต้องการของคุณมากนัก แต่บางทีการจัดเก็บจุดข้อมูลแต่ละจุดในฐานข้อมูลนั้นค่อนข้างเกินความสามารถ มันฟังดูคล้ายกับการจัดเก็บไลบรารี่รูปภาพโดยการเก็บแต่ละพิกเซลเป็นเรคคอร์ดแยกต่างหากในฐานข้อมูลเชิงสัมพันธ์

ตามกฎทั่วไปการจัดเก็บข้อมูลไบนารีในฐานข้อมูลนั้นส่วนใหญ่ผิดครั้ง โดยปกติจะมีวิธีที่ดีกว่าในการแก้ปัญหา แม้ว่าจะไม่ผิดที่เก็บข้อมูลแบบไบนารีในฐานข้อมูลเชิงสัมพันธ์ แต่บ่อยครั้งที่ข้อเสียมีมากกว่าผลกำไร ฐานข้อมูลเชิงสัมพันธ์ในฐานะชื่อ alludes ถึงเหมาะที่สุดสำหรับการจัดเก็บข้อมูลเชิงสัมพันธ์ ข้อมูลไบนารีไม่ใช่เชิงสัมพันธ์ มันเพิ่มขนาด (บ่อยครั้งมาก) ให้กับฐานข้อมูลสามารถสร้างความเสียหายต่อประสิทธิภาพการทำงานและอาจนำไปสู่คำถามเกี่ยวกับการรักษาอินสแตนซ์ MySQL จำนวนพันล้านระเบียน ข่าวดีก็คือมีฐานข้อมูลที่เหมาะอย่างยิ่งสำหรับการจัดเก็บข้อมูลไบนารี หนึ่งในนั้นในขณะที่ระบบไฟล์ของคุณไม่ชัดเจน เพียงแค่สร้างไดเรกทอรีและโครงสร้างการตั้งชื่อไฟล์สำหรับไฟล์ไบนารีของคุณ

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


5
ทำไมการจัดเก็บข้อมูลไบนารีในฐานข้อมูลจึงถือว่าผิด (ถามบางส่วนเพราะฉันอยากรู้ แต่ยังเพราะฉันสามารถคิดกรณีการใช้งานได้)

15
หากข้อมูลไบนารีไม่มีค่าเป็นเอกเทศข้อมูลนั้นไม่ควรถูกจัดเก็บเป็นแถวที่ไม่ซ้ำกัน พิกเซล 500x325 ในรูปภาพไม่เกี่ยวข้อง

1
นั่นเป็นจุดที่ดีมาก เราน่าจะเก็บไฟล์ raw ไว้ในกรณีที่เราต้องการดึงสิ่งออกมาอีกครั้งในภายหลัง แต่การเปรียบเทียบกับการจัดเก็บภาพเป็นสิ่งที่ยอดเยี่ยม เราไม่จำเป็นต้องเข้าถึงดาต้าพ้อยท์แต่ละตัวเลย (ยกเว้นว่าเราทำซ้ำการแตกไฟล์สูงสุด) ดังนั้นการเก็บข้อมูลสถิติที่แยกออกมาจะดีกว่ามาก
haxney

107

ฉันเคยทำงานกับฐานข้อมูล MySQL ที่มีขนาดใหญ่มาก (Terabyte +) ตารางที่ใหญ่ที่สุดที่เรามีมีอยู่มากกว่าหนึ่งพันล้านแถว นี่คือการใช้ MySQL 5.0 ดังนั้นจึงเป็นไปได้ว่าสิ่งต่าง ๆ อาจได้รับการปรับปรุง

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

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

เรามีตารางมากมายในช่วงแถวที่ 10-100 ล้าน การรวมที่สำคัญใด ๆ ลงในตารางใช้เวลานานเกินไปและอาจใช้เวลาตลอดไป ดังนั้นเราจึงเขียนกระบวนงานที่เก็บไว้เพื่อ 'เดิน' ตารางและกระบวนการรวมกับช่วงของ 'id ด้วยวิธีนี้เราจะประมวลผลข้อมูล 10-100,000 แถวต่อครั้ง (เข้าร่วมกับ id ของ 1-100,000 แล้ว 100,001-200,000 ฯลฯ ) นี่เร็วกว่าการเข้าร่วมกับทั้งตารางอย่างมีนัยสำคัญ

การใช้ดัชนีในตารางที่มีขนาดใหญ่มากซึ่งไม่ได้ขึ้นอยู่กับคีย์หลักนั้นก็ยากกว่าเช่นกัน Mysql 5.0 เก็บดัชนีในสองส่วน - มันเก็บดัชนี (นอกเหนือจากดัชนีหลัก) เป็นดัชนีไปยังค่าคีย์หลัก ดังนั้นการค้นหาที่ทำดัชนีจะทำในสองส่วน: MySQL ตัวแรกไปที่ดัชนีและดึงค่าคีย์หลักที่ต้องการค้นหาจากนั้นจะทำการค้นหาครั้งที่สองในดัชนีคีย์หลักเพื่อค้นหาว่าค่าเหล่านั้นอยู่ที่ไหน

สิ่งนี้คือการทำดัชนีสำหรับตารางที่มีขนาดใหญ่มาก (1-200 ล้านแถวบวก) กับตารางนั้นมีข้อ จำกัด คุณต้องการดัชนีที่น้อยลงและง่ายขึ้น และการทำประโยคเลือกอย่างง่ายที่ไม่ได้อยู่บนดัชนีโดยตรงอาจไม่กลับมา ส่วนคำสั่งจะต้องกดดัชนีหรือลืมไป

แต่ทั้งหมดที่ถูกกล่าวว่าสิ่งต่าง ๆ ใช้งานได้จริง เราสามารถใช้ MySQL กับตารางที่มีขนาดใหญ่มากเหล่านี้และทำการคำนวณและรับคำตอบที่ถูกต้อง

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

ฉันเห็นด้วยกับคำตอบของ srini.venigallaว่าการทำให้ข้อมูลกลับคืนสู่สภาพปกติอย่างบ้าคลั่งอาจไม่ใช่ความคิดที่ดีที่นี่ การเข้าร่วมหลายตารางด้วยข้อมูลจำนวนมากจะเปิดโอกาสให้คุณเสี่ยงต่อการเรียงลำดับไฟล์ซึ่งอาจหมายถึงข้อความค้นหาบางส่วนของคุณจะไม่กลับมาอีก การล้างข้อมูลด้วยปุ่มจำนวนเต็มง่าย ๆ จะทำให้คุณมีโอกาสประสบความสำเร็จมากขึ้น

ทุกสิ่งที่เรามีคือ InnoDB เกี่ยวกับ MyISAM กับ InnoDB: สิ่งที่สำคัญคือไม่ผสมสองอย่างนี้เข้าด้วยกัน คุณไม่สามารถปรับเซิร์ฟเวอร์ให้เหมาะสำหรับทั้งคู่ได้อย่างแท้จริงเนื่องจากวิธีที่ MySQL ใช้แคชกับคีย์และข้อมูลอื่น ๆ เลือกอย่างใดอย่างหนึ่งสำหรับตารางทั้งหมดในเซิร์ฟเวอร์ถ้าคุณสามารถ MyISAM อาจช่วยแก้ไขปัญหาความเร็วบางอย่าง แต่อาจไม่ช่วยงาน DBA โดยรวมที่ต้องทำ - ซึ่งอาจเป็นฆาตกร


1
MySQL ปรับปรุงแผนกจำนวนมากในดัชนี (... ) ตั้งแต่ 5.0 มันจะน่าสนใจเพื่อดูว่ามันทำงานอย่างไร
แหวนØ

70

normalizing ข้อมูลอย่างบ้าคลั่ง

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

Is this reasonable?

ฉันจะสร้างตารางแบนเพิ่มเติมพร้อมข้อมูลทั้งหมด

run_id | spectrum_id | data_id | <data table columns..> |

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

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


คุณวิเคราะห์ความต้องการในการเขียนของคุณกับความต้องการในการอ่านแล้วหรือยัง? มันจะเป็นการดึงดูดให้ทิ้ง SQL และไปที่กลไกการจัดเก็บข้อมูลที่ไม่ได้มาตรฐาน ในมุมมองของฉันมันควรจะเป็นทางเลือกสุดท้าย

เพื่อเร่งความเร็วในการเขียนคุณอาจต้องการลองใช้ Handler Socket Percona ถ้าฉันจำแพคเกจ Handler Socket ในแพ็คเกจการติดตั้งของพวกเขา (ไม่มีความสัมพันธ์กับ Percona!)

http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html


33

คำตอบสั้น ๆ คือใช่ที่ผ่านการรับรอง - เมื่อจำนวนแถวเพิ่มจำนวนสคีมาประเภทข้อมูลและการดำเนินการที่แม่นยำขึ้น

จำนวนข้อมูลปกติของคุณขึ้นอยู่กับการดำเนินการที่คุณวางแผนที่จะดำเนินการกับข้อมูลที่เก็บไว้ ตาราง 'ดาต้าพอยน์' ของคุณโดยเฉพาะดูเหมือนว่ามีปัญหา - คุณวางแผนที่จะเปรียบเทียบจุดที่ n จากสเปกตรัมที่ให้กับ mth อื่น ๆ หรือไม่? หากไม่จัดเก็บแยกต่างหากอาจเป็นข้อผิดพลาด หากดาต้าพอยท์ของคุณไม่โดดเดี่ยว แต่เหมาะสมในบริบทของสเปคตรัมที่เกี่ยวข้องคุณไม่จำเป็นต้องมีคีย์หลัก - รหัสต่างประเทศสำหรับสเปคตร้าและคอลัมน์ 'nth' (คอลัมน์ 'ดัชนี' ของคุณ) จะพอเพียง .

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

MySQL ที่ใหญ่ที่สุดที่ฉันเคยจัดการส่วนตัวคือประมาณ 100 ล้านแถว ที่ขนาดนี้คุณต้องการเก็บแถวของคุณและทำให้ขนาดของคุณคงที่ - ทำให้ MySQL สามารถคำนวณตำแหน่งของแถวใด ๆ ในตารางได้อย่างมีประสิทธิภาพโดยการคูณคูณขนาดคงที่ของแต่ละแถว (คิดเลขคณิตตัวชี้) - แม้ว่า รายละเอียดที่แน่นอนขึ้นอยู่กับเครื่องมือเก็บข้อมูลที่คุณวางแผนจะใช้ ใช้ MyISAM หากคุณสามารถหลีกเลี่ยงได้สิ่งที่ขาดความน่าเชื่อถือมันใช้ความเร็วและในสถานการณ์ของคุณก็ควรพอเพียง แทนที่ฟิลด์ขนาดตัวแปรเช่น VARCHAR ด้วย CHAR (n) และใช้ RTRIM () ในคิวรีการอ่านของคุณ

เมื่อแถวของตารางของคุณมีความกว้างคงที่คุณสามารถลดจำนวนไบต์ได้โดยการประเมินประเภทข้อมูลจำนวนเต็มของ MySQL อย่างระมัดระวัง(บางส่วนไม่ได้มาตรฐาน) การประหยัด 1 ไบต์ทุกครั้งคุณสามารถละทิ้งได้ด้วยการแปลง INT 4 ไบต์เป็น MEDIUMINT 3 ไบต์ช่วยให้คุณประหยัด ~ 1MB ต่อล้านแถว - หมายถึงดิสก์ I / O ที่น้อยลงและการแคชที่มีประสิทธิภาพมากขึ้น ใช้ประเภทข้อมูลที่เล็กที่สุดเท่าที่จะเป็นไปได้ที่คุณสามารถหลีกเลี่ยงได้ อย่างระมัดระวังประเมินชนิดลอยจุดและดูว่าคุณสามารถแทนที่คู่ 8 ไบต์ลอย 4 ไบต์หรือแม้กระทั่ง <8 ไบต์Numerics จุดคงที่ เรียกใช้การทดสอบเพื่อให้แน่ใจว่าสิ่งที่คุณเลือกจะไม่กัดคุณในภายหลัง

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

ที่สำคัญที่สุดไม่ว่าคุณจะลงมือทำอะไรอย่าคิดว่าคุณเลือกสคีมาที่สมบูรณ์แล้วสุ่มสี่สุ่มห้าเริ่มทิ้งเร็กคอร์ด 10 ล้านล้านรายการการออกแบบที่ดีต้องใช้เวลาในการพัฒนา สร้างชุดข้อมูลทดสอบขนาดใหญ่ แต่จัดการได้ (พูดได้ 1-5%) และตรวจสอบความถูกต้องและประสิทธิภาพของสกีมาของคุณ ดูการทำงานของการทำงานที่แตกต่างกัน (http://dev.mysql.com/doc/refman/5.0/en/using-explain.html) และตรวจสอบให้แน่ใจว่าคุณทำยอดคงเหลือในสคีมาของคุณเพื่อสนับสนุนการดำเนินงานที่พบบ่อยที่สุด

ฉันพูดสั้นไหม อ๊ะ อย่างไรก็ตามโชคดี!


23

ดูเหมือนว่าเหตุผลเดียวที่จะทำลายข้อมูลจุดข้อมูลออกจาก XML (ตรงข้ามกับข้อมูลเมตาเช่นเวลาและประเภทของการทำงาน) และในรูปแบบฐานข้อมูลคือเมื่อคุณวิเคราะห์สเปกตรัมในอาร์เรย์ - เช่นบางทีการค้นหาทั้งหมด ทำงานด้วยลายเซ็นบางอย่าง มีเพียงคุณเท่านั้นที่รู้โดเมนปัญหาของคุณในตอนนี้ แต่อาจคล้ายกับการจัดเก็บเพลงตัวอย่างที่ 96kHz ด้วย 1 ตัวอย่างต่อแถว ฉันไม่แน่ใจว่าขนาดเป็นปัญหามากกว่าการใช้ข้อมูล การค้นหาข้อมูลจะเทียบเท่ากับการถามแอมพลิจูดสัมพัทธ์ 2 นาทีในเพลงในทุกเพลงของ The Beatles หากคุณรู้ว่าการวิเคราะห์ชนิดใดที่อาจต้องดำเนินการอาจเป็นไปได้มากที่การดำเนินการเหล่านี้กับสัญญาณและการจัดเก็บข้อมูลเหล่านั้นในข้อมูลเมตาเกี่ยวกับการดำเนินการอาจทำให้เข้าใจได้มากกว่า

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

ดังนั้นเช่นคำถามมากมายก่อนถามเกี่ยวกับ MySQL ในการจัดการแบบจำลองของคุณการย้อนกลับไปดูรูปแบบและวิธีการใช้งานนั้นน่าจะเหมาะสมกว่ากังวลเกี่ยวกับประสิทธิภาพในขณะนี้


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


18

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

ประสิทธิภาพที่นี่ใช้ได้ มันเป็นข้อมูลปกติมาก อย่างไรก็ตาม - ข้อกังวลหลักของฉันเกี่ยวกับการอ่านนี้คือคุณจะมีคะแนนมากกว่า 4.2 พันล้านแถวสำหรับตารางเหล่านี้ (อาจไม่ใช่ "รัน" แต่อาจเป็นอีกสองรายการ) ซึ่งหมายความว่าคุณจะต้องใช้ BIGINT แทน INT สำหรับ คีย์หลัก / ต่างประเทศ

ประสิทธิภาพของ MySQL ที่มีฟิลด์ BIGINT ในคอลัมน์ที่จัดทำดัชนีนั้นน่ากลัวมากเมื่อเปรียบเทียบกับ INT ฉันทำผิดพลาดในการทำสิ่งนี้เพียงครั้งเดียวโดยใช้โต๊ะฉันคิดว่าอาจโตกว่าขนาดนี้และเมื่อมันตีสองสามร้อยล้านแถวการแสดงก็ไม่น่าดู ฉันไม่มีตัวเลขดิบ แต่เมื่อฉันพูดไม่ดีฉันหมายถึง Windows ME ไม่ดี

คอลัมน์นี้เป็นคีย์หลัก เราแปลงมันกลับเป็นแค่ INT และ presto magico การแสดงก็ดีอีกครั้ง

เซิร์ฟเวอร์ทั้งหมดของเราในเวลานั้นใช้ Debian 5 และกับ MySQL 5.0 เราได้อัปเกรดเป็น Debian 6 และ Percona MySQL 5.5 แล้วดังนั้นสิ่งต่างๆอาจจะดีขึ้นตั้งแต่นั้นมา แต่จากประสบการณ์ของฉันที่นี่ไม่ฉันไม่คิดว่ามันจะทำงานได้ดีมาก


17

ไม่ว่าจะใช้งานได้หรือไม่คุณมักจะพบปัญหาเดียวกันกับสื่อบันทึกข้อมูลขนาดใหญ่ก้อนเดียว: ดิสก์ช้า ที่ 100 MB / s (ค่อนข้างดีสำหรับสปินนิ่งมีเดีย) ใช้เวลา 3 ชั่วโมงในการอ่านตาราง 1TB; นั่นคือสมมติว่าไม่มีการวิเคราะห์หรือการค้นหาหรือความล่าช้าอื่น ๆ ทำให้คุณช้าลง

นี่คือเหตุผลที่เกือบทุกการติดตั้ง "ข้อมูลขนาดใหญ่" ใช้แหล่งเก็บข้อมูลแบบกระจาย คุณสามารถใช้เงินสร้างคอมพิวเตอร์ได้อย่างน่าอัศจรรย์ถึง 8 เท่าเพื่อสร้าง DB ของคุณ แต่ถ้าคุณมีข้อมูลจำนวนมากที่สามารถสแกนแบบขนานคุณจะดีกว่าการกระจายโหลดไปยังคอมพิวเตอร์ราคาถูกกว่า 8 เครื่อง

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


13

อืม ... ฉันเห็นเหตุผลสองประการว่าทำไมคุณถึงเลือกโครงสร้างข้อมูลชนิดนี้:

  • คุณจำเป็นต้องทำดาต้าพอยน์ใด ๆ เทียบกับเคียวรีดาต้าพอยน์ใด ๆ
  • คุณตั้งใจที่จะดำเนินการตรรกะทั้งหมดของคุณใน SQL

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

PS: โปรดทราบว่าคุณจะต้องมีอย่างน้อย 36 + 5 ไบต์ต่อจุดข้อมูลดังนั้นด้วย 200B ดาต้าพอยน์ที่ควรให้พื้นที่อย่างน้อย 8.2 TB

PPS: คุณไม่ต้องการidคอลัมน์ในdatapointsตารางPRIMARY KEY (spectrum_id, index)อาจพอเพียง (โปรดระวังว่าindexอาจเป็นคำสงวน)


12

แก้ไข:

อย่าทำสิ่งนี้ด้วยข้อมูลที่เก็บไว้ในดิสก์เดี่ยว เพียงแค่อ่านข้อมูลจำนวนหนึ่งจากสื่อที่ใช้เวลานาน คุณต้องลดขนาดไม่ขึ้น

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

คำตอบเดิมด้านล่างบรรทัด


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

ถ้าคุณต้องการที่จะทำ ad-hoc เพิ่มเติมสอบถามวิธีแก้ปัญหาBigQuery ของ Googleอาจเหมาะสำหรับคุณ การนำเสนอที่เกี่ยวข้องจาก Google I / O 2012: การบีบอัดข้อมูลขนาดใหญ่ด้วย BigQuery

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


9

ไม่มีใครพูดถึงดังนั้นคำแนะนำของฉัน ดูโซลูชันMySQL ที่อัดแน่นอย่างหนาแน่น ยกตัวอย่างเช่นเห็นนี้ได้รับการยกย่องในการนำเสนอลิขสิทธิ์

แนวคิดคือ:

  • แทนที่จะเป็นหนึ่งฐานข้อมูลขนาดใหญ่พิเศษ
  • ใช้ตัวเล็ก ๆ จำนวนมากที่ถือส่วนต่าง ๆ ของข้อมูลต้นฉบับ

ดังนั้นคุณสามารถปรับขนาดในแนวนอนแทนที่จะพยายามปรับปรุงประสิทธิภาพในแนวตั้ง BigTableและGFSของ Google ยังใช้โหนดที่ปรับขนาดได้ในแนวนอนราคาถูกเพื่อจัดเก็บและค้นหาข้อมูลเพตาไบต์

อย่างไรก็ตามจะมีปัญหาหากคุณจำเป็นต้องเรียกใช้แบบสอบถามมากกว่าเศษที่แตกต่างกัน


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


7

ข้อมูลประเภทใดที่จะถูกเก็บไว้ในเครื่อง? มันเป็นอุปกรณ์เก็บข้อมูลที่แชร์หรือไม่

ปัจจัยที่ดีที่สุดที่จะบอกเวลาแบบสอบถามของคุณจะเป็นของคุณ harddrives ฐานข้อมูลและเครื่องมือเพิ่มประสิทธิภาพคิวรีได้รับการออกแบบมาเพื่อลดจำนวนดิสก์ I / O ให้มากที่สุด ระบุว่าคุณมีเพียง 3 โต๊ะสิ่งนี้จะทำได้อย่างน่าเชื่อถือ

ความเร็วในการอ่าน / เขียนของ harddrive นั้นช้ากว่าความเร็วหน่วยความจำ 200-300 เท่า ค้นหา harddrives ด้วยเวลาแฝงที่รวดเร็วมากและความเร็วในการอ่านและเขียนที่รวดเร็ว หากข้อมูลทั้งหมดนี้อยู่ในไดรฟ์ 2 TB หนึ่งอาจเป็นไปได้ว่าคุณจะต้องรอเป็นเวลานานเพื่อให้การค้นหาเสร็จสิ้น เวลาแฝงของฮาร์ดไดรฟ์อยู่ที่ประมาณ 10-15 มิลลิวินาทีในขณะที่เวลาแฝงของหน่วยความจำน้อยกว่า 10 มิลลิวินาที เวลาแฝงของฮาร์ดไดรฟ์อาจช้ากว่าหน่วยความจำแฝง 1000-2000x การเคลื่อนที่ของแขนกลบนฮาร์ดไดรฟ์เป็นสิ่งที่ช้าที่สุดในระบบทั้งหมดนี้

คุณมี RAM เท่าใด 16 กิกะไบต์? ให้บอกว่าช่วยให้คุณเก็บ 32 บันทึก คุณมีไฟล์ 16000 ไฟล์ หากคุณต้องการสแกนข้อมูลเชิงเส้นทั้งหมดคุณสามารถลงเอยด้วยการใช้เวลา 5-10 วินาทีในการหาเวลาเพียงอย่างเดียว หากรวมอัตราการถ่ายโอน 50mb / s แล้ว ประมาณ 7 ชั่วโมง นอกจากนี้ข้อมูลใด ๆ ที่บันทึกไว้ชั่วคราวจะต้องถูกจัดเก็บไว้ใน harddirve เพื่อให้มีที่ว่างสำหรับการอ่านข้อมูลใหม่

หากคุณกำลังใช้อุปกรณ์จัดเก็บข้อมูลร่วมที่มีการใช้งานอย่างแข็งขันโดยผู้ใช้รายอื่น ... ทางออกที่ดีที่สุดของคุณคือการทำงานทุกอย่างในเวลากลางคืน

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

การปรับให้เหมาะสมของแบบสอบถามสามารถดูได้ครั้งละ 1 คิวรีเท่านั้น ดังนั้นคำสั่ง Select ที่ซ้อนกันจะไม่สามารถปรับให้เหมาะสม อย่างไรก็ตามหากคุณทราบว่าแบบสอบถามแบบซ้อนเฉพาะจะส่งผลให้ชุดข้อมูลขนาดเล็กถูกส่งคืนให้เก็บไว้ การปรับให้เหมาะสมของแบบสอบถามใช้ฮิสโทแกรมและสมมติฐานคร่าว ๆ หากคุณรู้อะไรเกี่ยวกับข้อมูลและแบบสอบถามจากนั้นดำเนินการต่อ

ยิ่งคุณรู้เกี่ยวกับวิธีจัดเก็บข้อมูลบนดิสก์ของคุณมากเท่าไหร่คุณก็ยิ่งสามารถเขียนคิวรีของคุณได้เร็วขึ้นเท่านั้น หากทุกอย่างถูกจัดเก็บตามลำดับบนคีย์หลักอาจเป็นประโยชน์ในการเรียงลำดับคีย์หลักที่ส่งคืนจากแบบสอบถามซ้อน นอกจากนี้หากคุณสามารถลดชุดของชุดข้อมูลที่คุณต้องวิเคราะห์ก่อนทำ คุณดูที่การถ่ายโอนข้อมูลประมาณ 1 วินาทีต่อไฟล์ทั้งนี้ขึ้นอยู่กับระบบของคุณ

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

เท่าที่ความคิดเห็นเกี่ยวกับ denormalizing ตาราง ฉันคิดว่ามันเป็นการดีที่สุดที่จะเก็บดาต้าพอยน์ไว้ในกลุ่มที่ใหญ่กว่า (อาจเป็น spectra) จากนั้นทำการวิเคราะห์ข้อมูลในไพ ธ อนหรือภาษาที่โต้ตอบกับฐานข้อมูล ถ้าคุณไม่มี SQL-Wizard


3
คุณเน้นถึงความแตกต่างอย่างมากในฮาร์ดไดรฟ์เทียบกับความหน่วงของหน่วยความจำ แต่ตัวเลขของคุณจะปิดอยู่ที่ 1,000 หากฮาร์ดไดรฟ์มีเวลาในการตอบสนองประมาณ 10ms และหน่วยความจำ 10ns เวลาแฝงจะไม่แตกต่างกัน 1,000,000!
spectre256

6

สำหรับฉันดูเหมือนว่าสถานการณ์การใช้งานที่คุณต้องการบางอย่างเช่น "ที่จัดเก็บคอลัมน์เชิงสัมพันธ์" ตามที่อธิบายไว้ที่นี่ตามที่อธิบายไว้ที่นี่

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

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

ฉันอาจเข้าใจผิดถึงปัญหาจริง ๆ และฉันไม่ได้แนะนำวิธีแก้ไขปัญหาเฉพาะ

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


6

ฉันขอแนะนำให้คุณลองและแบ่งพาร์ติชันตารางของคุณ เรามีมากกว่า 80 ล้านแถวในตารางเดียว (ข้อมูลตลาดหุ้น) และไม่มีปัญหาในการเข้าถึงอย่างรวดเร็ว

ขึ้นอยู่กับว่าคุณต้องการค้นหาข้อมูลของคุณอย่างไรคุณควรออกแบบพาร์ติชันของคุณ ในกรณีของเราโดยวันที่ทำงานได้ดีเพราะเราค้นหาวันที่เฉพาะเจาะจง

http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations.html

http://www.slideshare.net/datacharmer/mysql-partitions-tutorial


5

ใช่ แต่...

ฉันทำงานกับตารางที่มี 2 พันล้านแถว อย่างไรก็ตามคาดว่าเฉพาะแบบสอบถามที่ใช้ PK จะเร็ว

สิ่งสำคัญที่สุดคือฮาร์ดแวร์มี RAM เพียงพอที่จะพอดีกับทั้งตารางในหน่วยความจำ เมื่อนั้นกลายเป็นปัญหา (สูงสุดที่ 96GB ในเวลานั้น) ไปสำหรับการแบ่งพาร์ติชันตามแนวตั้งทำให้ขนาดของชุดโต๊ะในแต่ละเครื่องเล็กพอที่จะยังพอดีกับหน่วยความจำ นอกจากนี้เครื่องยังเชื่อมต่อผ่านไฟเบอร์ 10Gb ดังนั้นปริมาณงานผ่านเครือข่ายจึงไม่ค่อยเป็นปัญหา

BTW สกีมาของคุณดูเหมือนบางอย่างซึ่งสามารถปรับให้เหมาะกับโซลูชัน NoSQL โดยใช้ run_idเป็นคีย์การแฮชสำหรับ spectra และspectrum_idเป็นคีย์การแฮชสำหรับจุดข้อมูล


4

ฉันเขียนเกี่ยวกับหัวข้อนี้ในบล็อกของฉัน: http://www.tocker.ca/2013/10/24/improving-the-performance-of-large-tables-in-MySQL.html

ในการทำซ้ำจุดสำคัญบางส่วน:

  • B-trees ลดลงเนื่องจากมีขนาดใหญ่ขึ้นและไม่เหมาะกับหน่วยความจำ (MySQL ไม่ได้อยู่คนเดียวที่นี่)
  • InnoDB มีคุณสมบัติบางอย่างที่จะช่วยรักษาประสิทธิภาพไว้ (เปลี่ยนบัฟเฟอร์ก่อนหน้านี้เรียกว่า 'insert buffer')
  • การแบ่งพาร์ติชันยังสามารถช่วยได้

ในความคิดเห็นของโพสต์ของฉัน Tim Callaghan เชื่อมโยงกับสิ่งนี้: http://www.tokutek.com/resources/benchmark-results/benchmarks-vs-innodb-hdds/#iiBench

ซึ่งแสดงการแทรก 1 พันล้านแถวโดยใช้เกณฑ์มาตรฐาน iibench

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