สแกนหนึ่งล้านแถวในฐานข้อมูลที่รวดเร็ว


9

พื้นหลัง

ฐานข้อมูลท้องถิ่นมีแถวที่ไม่ซ้ำกันเกือบ 1.3 พันล้านแถว แต่ละแถวมีความสัมพันธ์ทางอ้อมกับละติจูดและลองจิจูดเฉพาะ (ตำแหน่ง) แต่ละแถวมีการประทับวันที่

ใช้ Case

ปัญหาดังต่อไปนี้:

  1. ผู้ใช้ตั้งวันที่เริ่มต้น / สิ้นสุดและช่วงของค่า (เช่น 100 ถึง 105)
  2. ระบบรวบรวมแถวทั้งหมดที่ตรงกับวันที่กำหนดจัดกลุ่มตามสถานที่
  3. ระบบดำเนินการกำหนดสถานที่ที่ในช่วงวันที่เหล่านั้นมีความเป็นไปได้ทางสถิติของการตกอยู่ในช่วงของค่าที่กำหนด
  4. ระบบจะแสดงตำแหน่งที่ตรงกันทั้งหมดให้กับผู้ใช้

นี่เป็นปัญหาของความเร็วและสเกล

คำถาม

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

ระบบปัจจุบัน

สภาพแวดล้อมปัจจุบัน:

  • PostgreSQL 8.4 (สามารถปรับรุ่นได้การสลับฐานข้อมูลไม่ใช่ตัวเลือก)
  • R และ PL / R
  • XFS
  • WD VelociRaptor
  • RAM 8 GB (Corsair G.Skill; 1.3 GHz)
  • Quad core GenuineIntel 7 (2.8 GHz)
  • Ubuntu 10.10

สามารถอัพเกรดฮาร์ดแวร์ได้

อัพเดท - โครงสร้างฐานข้อมูล

พันล้านแถวอยู่ในตารางคล้าย:

id | taken | location_id | category | value1 | value2 | value3
  • id - คีย์หลัก
  • ถ่าย - วันที่กำหนดให้กับแถว
  • location_id - อ้างอิงถึงละติจูด / ลองจิจูด
  • หมวดหมู่ - คำอธิบายของข้อมูล
  • value1 .. 3 - ค่าอื่น ๆ ที่ผู้ใช้สามารถสืบค้นได้

โดยtakenทั่วไปคอลัมน์จะเป็นวันที่ต่อเนื่องกันlocation_idบางครั้งสถานที่แต่ละแห่งมีข้อมูลตั้งแต่ 1800 ถึง 2010 (ประมาณ 77,000 วันที่ส่วนใหญ่จะซ้ำกันเนื่องจากแต่ละสถานที่มีข้อมูลในช่วงวันที่เดียวกัน)

มีเจ็ดหมวดหมู่และตารางจะแบ่งตามหมวดหมู่แล้ว (โดยใช้ตารางย่อย) แต่ละหมวดหมู่มีประมาณ 190 ล้านแถว ในอนาคตอันใกล้จำนวนแถวต่อหมวดหมู่จะเกินหนึ่งพันล้าน

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

ไอเดีย

ความคิดบางอย่างที่ฉันมีรวมถึง:

  • ค้นหาบริการคลาวด์เพื่อโฮสต์ฐานข้อมูล
  • สร้างแถบตรวจค้น SSD (วิดีโอยอดเยี่ยม)
  • สร้างตารางที่รวมตำแหน่งที่ตั้งทั้งหมดตามเมือง (การคำนวณล่วงหน้า)

ขอบคุณ!


10
"การสลับฐานข้อมูลไม่ใช่ตัวเลือก" ซึ่งช่วยกำจัดโซลูชันส่วนใหญ่ได้ โชคดี!
Steven A. Lowe

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

2
@Dave: ระบบปัจจุบันใช้เวลาเท่าไหร่? ระบบปัจจุบันใช้PostGISหรือไม่ คือหรือหรือหมายถึงตารางที่สอง? มีการจัดทำดัชนีคอลัมน์หรือไม่ location_idgeographygeometrylocation_id

1
@ Thorbjørn & @Darknight - ในส่วนความคิดที่ฉันแสดงรายการการคำนวณล่วงหน้าซึ่งจะลดข้อมูลให้เหลือหนึ่งค่าต่อเมืองต่อวัน (ต่อหมวดหมู่) การคำนวณอาจเกิดขึ้นทุกปีหรือแม้กระทั่งทุกเดือนฉันคิดว่า นี่คือแผนของฉันหากไม่มีความเป็นไปได้อื่น ๆ (การคำนวณอาจใช้เวลาหลายสัปดาห์)
Dave Jarvis

1
@Dave มีความเป็นไปได้มากมาย แต่คำถามก็คือสิ่งที่เกี่ยวข้องกับคุณ คุณได้ตรวจสอบว่าคอขวดปัจจุบันอยู่ที่ไหน

คำตอบ:


12

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

หากคุณสแกนแบบเต็มตารางคุณต้องมีดัชนีที่เหมาะสม

หากคุณรอ I / O คุณต้องมีหน่วยความจำเพิ่มเติมสำหรับการแคช (Jeff Atwood เพิ่งกล่าวถึงว่าระบบ 24 Gb สามารถเข้าถึงได้บนระบบเดสก์ท็อป)

หากคุณรอ CPU คุณต้องดูว่าการคำนวณของคุณสามารถเพิ่มประสิทธิภาพได้หรือไม่

สิ่งนี้ต้องใช้หมวก DBA ที่แหลมและระบบปฏิบัติการหมวก แต่ก็คุ้มค่าเพื่อให้แน่ใจว่าคุณกำลังเห่าต้นไม้ที่เหมาะสม


คุณหั่นและหั่นเป็นชิ้นขนาดไหน - แม้ว่าแต่ละแถวจะมีเพียง 100 ไบต์, 1.3 พันล้านแถว = 121 GB ด้วยดัชนีของคุณเป็นต้นฉันมั่นใจว่ามันจะมีมากขึ้น ในกล่องเดียวคุณจะช้าถ้าคุณไม่มีฮาร์ดแวร์ที่จริงจังบางอย่างรอบ SSD + หน่วยความจำจำนวนมาก วิธีที่ถูกกว่าคือการไต่ระดับข้ามกล่อง
Subu Sankara Subramanian

4
@Subu คุณต้องการกระจายหรือไม่ ตอนนี้คุณมีปัญหาสองอย่าง ...

Heh - ที่ฉันเห็นด้วย :) แต่มันถูกกว่า!
Subu Sankara Subramanian

@ Thorbjørn: ขอบคุณสำหรับเวลาและความช่วยเหลือของคุณ ฉันคิดว่าฉันจะลดชุดข้อมูลเป็น 25 ล้านแถวต่อหมวดหมู่จากนั้นใช้ดัชนีในวันที่ ซึ่งควรลดการสแกนถึง ~ 70000 แถว (ต่อวันโดย จำกัด ช่วงสองสัปดาห์สำหรับช่วง) ซึ่งน่าจะค่อนข้างเร็ว
Dave Jarvis

@ เดฟคุณต้องรู้ว่าคอขวดของคุณอยู่ที่ไหน เรียนรู้มันในขณะที่คุณไม่ได้มีการ

4

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

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


ขอบคุณสำหรับความคิด อาจมี 77,066 วันและวันที่ใหม่จะถูกเพิ่มไปข้างหน้า ฉันมีเครื่องเดียว มีสถานที่ 20,000 แห่ง แต่การแยกตามสถานที่ไม่ได้ช่วยเพราะข้อมูลในการวิเคราะห์ครอบคลุมทุกสถานที่
Dave Jarvis

และการใช้คลาวด์ต่างจากโซลูชันข้างต้นอย่างไร
Chani

นี่คือสิ่งที่ฉันคิดเช่นกัน พาร์ติชันแนวนอนบางชนิดเพื่อให้การค้นหาสามารถเกิดขึ้นพร้อมกันในทุกพาร์ติชัน
davidk01

การแยกในวันนั้นอาจเป็นประโยชน์มากที่สุดส่งผลให้มีตารางแยกกัน 2562 ตาราง (366 วัน x 7 หมวดหมู่)
Dave Jarvis

4

สถานการณ์กรณีที่เลวร้ายที่สุดคือช่วงวันที่ครอบคลุมวันที่ทั้งหมดในฐานข้อมูลของคุณ

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

รับพารามิเตอร์เหล่านี้ฉันจะบอกว่าเป็นไปไม่ได้

เพียงดูที่ฮาร์ดไดรฟ์ของคุณ: อัตราสูงสุดที่น้อยกว่า 150MB / s การอ่าน 1.3 พันล้านระเบียนจะใช้เวลามากกว่า 5 วินาที CPU-wise คุณจะไม่สามารถทำการวิเคราะห์ทางสถิติใน 1.3 พันล้านระเบียนใน 5 วินาที

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

อาจเป็นไปได้ที่จะเก็บบันทึกทั้งหมด (หรืออย่างน้อยก็ส่วนที่สำคัญ) ไว้ในหน่วยความจำ อาจไม่ได้อยู่ใน 8GB อย่างน้อยก็จะกำจัดส่วนของดิสก์ I / O แม้ว่าแบนด์วิดท์หน่วยความจำอาจไม่เพียงพอในการสแกนทุกอย่างใน 5 วินาที นี่เป็นอีกเทคนิคหนึ่งในการเร่งความเร็วแอปพลิเคชั่นเหล่านี้ (รวมกับคำแนะนำก่อนหน้าของฉัน)

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


ขอบคุณสำหรับคำตอบ การอัพเกรดฮาร์ดแวร์เป็นการพิจารณาตามความคิดที่ฉันระบุไว้ วิธีแก้ปัญหาย่อย $ 750 USD น่าจะเหมาะสมที่สุด
Dave Jarvis

2

ฉันสองความเห็นของ rwong คำถาม: PostgreSQL เสนอประเภทดัชนีและเครื่องมือที่เหมาะสม (ดัชนี GIST, ดัชนี GIN, Postgis, ประเภทเรขาคณิต) ในลักษณะที่ geodata และข้อมูลที่เกี่ยวข้องกับ datetime ควรค้นหาตามเกณฑ์ที่ไม่มีปัญหามาก

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


ขอบคุณ. ตารางลูกทั้งเจ็ดถูกจัดกลุ่มในตำแหน่งวันที่และหมวดหมู่โดยใช้ btree ฉันค้นคว้าดัชนี GIN เมื่อปีที่แล้วและพวกเขาไม่ได้ช่วย (หรือจะไม่) อย่างที่ฉันจำได้
Dave Jarvis

2
ตำแหน่งการจัดทำดัชนีตาม B-Tree ไม่ใช่สิ่งที่มีประโยชน์แม้แต่น้อยเมื่อพิจารณาถึงประเภทการค้นหาที่คุณกำลังมองหา คุณต้องมีดัชนีกลับด้านที่ทำงานกับตัวดำเนินการที่จำเป็นซึ่งในกรณีของ Postgis มักจะหมายถึง GIST คุณอาจต้องการที่จะเน้นไม่กี่คำสั่งช้า ...
เดนิสเดอ Bernardy

1

เมื่อคุณใช้ข้อมูล PostgreSQL และละติจูด / ลองจิจูดคุณควรใช้ PostGIS ด้วยเช่นกันวิธีที่คุณสามารถเพิ่มดัชนีอวกาศ GiST ลงในฐานข้อมูลของคุณเพื่อช่วยเร่งความเร็ว

ฉันมีตารางดังกล่าว (ที่มีแถว 350k) ที่มีการกำหนดค่าน้อยกว่าของคุณมาก (2 คอร์และแทบ 2Gb RAM) แต่การค้นหาใช้เวลาน้อยกว่าหนึ่งวินาที


0

บางทีคุณอาจทำลายโมเดลเชิงสัมพันธ์อย่าง Essbase กับสถาปัตยกรรม OLAP ของพวกเขา: Essbase Wikipedia

สิ่งที่ฉันหมายถึงคือการสร้างหนึ่งตารางต่อเมืองดังนั้นลงท้ายด้วย 1,000+ ตาราง ไม่ใช่ตารางเดียวที่คุณแนะนำ แต่มีหลายตาราง จัดทำดัชนีแต่ละตารางตามวันที่และตำแหน่ง หลายตารางหลายดัชนี -> เร็วขึ้น


ขอบคุณสำหรับการบันทึก มีเมืองมากกว่า 70,000 แห่งและค่าละติจูด / ลองจิจูดแตกต่างกันมากมายอยู่ในพื้นที่เมืองเฉพาะ
Dave Jarvis

@Dave: คุณสามารถสร้างแผนภาพ voronoi สำหรับเมืองต่างๆและจำแนกค่า lat / lon เป็น tessellations ได้หรือไม่? (เช่นถ้าฟังดูเหมือนจับจดให้เป็น) จากนั้นในระหว่างการค้นหาคุณจะค้นหาเมืองทั้งหมดที่มีเทสเซลเลชันแตะช่วงละติจูด / ลองจิจูดของข้อความค้นหา หากเทสโทเลชั่นของ voronoi ช้าเกินไปกล่องสี่เหลี่ยม (เช่น 5 deg lat x 5 deg lon) อาจคุ้มค่าที่จะลอง

0

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


-2

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

และเชื่อคุณฉันฉันไม่ได้มาจาก intersystems ;-)

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