วิธีจัดการข้อมูล 3.1 พันล้านแถว


14

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

มีการเพิ่มข้อกำหนดล่าสุดเพื่อติดตามmin/ max/ sumค่าสำหรับชั่วโมงที่ผ่านมา

หมายเหตุ: โดยหลักการแล้วฉันต้องการพิจารณาตัวเลือก MongoDB แต่ฉันต้องแสดงให้เห็นว่าฉันได้ใช้ตัวเลือก SQL-Server หมดแล้ว

ข้อมูล

ตารางต่อไปนี้แสดงถึงแหล่งข้อมูลหลัก (สอบถามบ่อยที่สุด) ตารางจะมีแถวประมาณห้าล้านแถว การเปลี่ยนแปลงข้อมูลส่วนใหญ่จะเป็นUPDATEคำสั่งที่มีข้อความเป็นครั้งคราวมากINSERTหลังจากการโหลดข้อมูลเริ่มต้น ฉันเลือกที่จะจัดกลุ่มข้อมูลตามdataPointIdที่คุณจะเลือกall values for a given data pointเสมอ

// Simplified Table
CREATE TABLE [dbo].[DataPointValue](
    [dataPointId]  [int] NOT NULL,
    [valueId]      [int] NOT NULL,
    [timestamp]    [datetime] NOT NULL,
    [minimum]      [decimal](18, 0) NOT NULL,
    [hourMinimum]  [decimal](18, 0) NOT NULL,
    [current]      [decimal](18, 0) NOT NULL,
    [currentTrend] [decimal](18, 0) NOT NULL,
    [hourMaximum]  [decimal](18, 0) NOT NULL,
    [maximum]      [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointValue] PRIMARY KEY CLUSTERED ([dataPointId],[valueId])
)

ตารางที่สองมีขนาดใหญ่กว่าประมาณ 3.1 พันล้านแถว (แสดงถึงข้อมูลในช่วงหกเดือนที่ผ่านมา) ข้อมูลที่เก่ากว่าหกเดือนจะถูกลบทิ้ง มิฉะนั้นจะมีการINSERTรายงานข้อมูลอย่างเข้มงวด(ประมาณ 200 แถว / วินาที 720,000 แถว / ชั่วโมง 17 ล้านแถว / สัปดาห์)

// Simplified Table
CREATE TABLE [dbo].[DataPointValueHistory](
    [dataPointId] [int]            NOT NULL,
    [valueId]     [int]            NOT NULL,
    [timestamp]   [datetime]       NOT NULL,
    [value]       [decimal](18, 0) NOT NULL,
    [delta]       [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointHistory] PRIMARY KEY CLUSTERED ([dataPointId], [valueId], [timestamp])

)

ความคาดหวังคือตารางนี้จะมีขนาดใหญ่เป็นสองเท่าเนื่องจากจำนวนค่าจุดข้อมูลที่ถูกติดตามเพิ่มขึ้นเป็น 400 แถว / วินาที

คำถาม (ใช่ฉันถามมากกว่าหนึ่ง ... พวกเขาทั้งหมดที่เกี่ยวข้องอย่างใกล้ชิด)

ขณะนี้ฉันใช้ฐานข้อมูล SQL-Server 2008 R2 Standard Edition ฉันน่าจะทำให้เป็นกรณีสำหรับการอัพเกรดเป็น Enterprise Edition หากสามารถรับระดับประสิทธิภาพที่ต้องการด้วยพาร์ทิชันตาราง (หรือ MongoDB ถ้าไม่สามารถตีระดับประสิทธิภาพที่ต้องการด้วย SQL-Server) ฉันต้องการให้คุณป้อนข้อมูลต่อไปนี้:


1) ระบุว่าฉันจะต้องคำนวณmin, maxและsumสำหรับชั่วโมงที่ผ่านมา (ในnow - 60 minutes) วิธีที่ดีที่สุดในการติดตามข้อมูลล่าสุดคืออะไร:

  • เก็บข้อมูลล่าสุดในหน่วยความจำของบริการข้อมูล เขียนคำนวณต่ำสุด / สูงสุด / เฉลี่ยกับแต่ละข้อมูล UPDATE

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

  • เก็บประวัติล่าสุดในแถว DataPointValue เองเพื่อหลีกเลี่ยงการค้นหาตารางประวัติหรือไม่ อาจเก็บไว้เป็นสตริงที่มีการคั่นและประมวลผลภายใน UPDATE proc หรือไม่

  • ตัวเลือกอื่นที่ฉันไม่ได้พิจารณา?


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

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

  • ทำคลัสเตอร์DataPointValueHistoryตาม dataPointId -> valueId -> timeStamp

  • ทำคลัสเตอร์DataPointValueHistoryตาม timeStamp -> dataPointId -> valueId


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

  • หากทำคลัสเตอร์โดยการประทับเวลาก่อนฉันคิดว่าข้อมูลควรถูกแบ่งพาร์ติชันตามสัปดาห์ (รวม 27 พาร์ติชัน) พาร์ทิชันที่เก่าแก่ที่สุดจะถูกกำจัดหลังจากสัปดาห์ที่ 27

  • หากทำคลัสเตอร์โดย dataPointId ก่อนฉันคิดว่าควรแบ่งพาร์ติชันโดยโมดูลัสของ id หรือไม่

เนื่องจากฉันมีประสบการณ์ จำกัด ในการแบ่งพาร์ติชันตารางความเชี่ยวชาญของคุณจะได้รับการชื่นชม


คุณลบรุ่นของคำถามนี้ใน StackOverflow หรือไม่
Taryn

@bluefeet - ใช่ถูกตั้งค่าสถานะเป็นนอกหัวข้อ ... ดังนั้นฉันจึงลบคำถาม SO และสร้างขึ้นใหม่ที่นี่ (ฉันน่าจะรอให้ย้ายข้อมูล)
Calgary Coder

ไม่มีปัญหาฉันแค่ทำให้แน่ใจว่าเราไม่มีคำถามข้ามโพสต์
Taryn

ใน Standard Edition คุณยังสามารถแบ่งพาร์ติชันข้อมูลโดยใช้มุมมองที่แบ่งพาร์ติชันและตารางฐานหลายตาราง ไม่แน่ใจว่าคุณคิดเช่นนั้นหรือไม่
Jon Seigel

@ จอน - ใช่ฉันได้พิจารณาพาร์ติชันตารางด้วยตนเอง (ตัวเลือกนั้นจะขึ้นอยู่กับว่ามีไลเซนส์องค์กรหรือไม่ ... ถ้าใช่ทำไมต้องมีบทบาทของตัวเอง)
Calgary Coder

คำตอบ:


4

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

http://leiliweb.wordpress.com/2012/12/11/partitioned-table-and-index-strategies-using-sql-server-2008/


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