Wie verwaltet man 3,1 Milliarden Datenzeilen?

14

Ich bin derzeit mit der Implementierung eines Speicherschemas für eine relativ große Datenmenge beauftragt. Auf die Daten wird in erster Linie zugegriffen, um einen aktuellen data pointWert zu bestimmen , aber ich muss auch die letzten sechs Monate des Verlaufs für Datentrends / -analysen nachverfolgen.

Eine kürzliche Forderung wurde hinzugefügt , um das zu verfolgen min/ max/ sumWert für die letzte Stunde.

ANMERKUNG: Idealerweise würde ich gerne eine MongoDB-Option in Betracht ziehen, aber ich muss zuerst nachweisen, dass ich die SQL-Server-Optionen ausgeschöpft habe.

Die Daten

Die folgende Tabelle stellt die primäre Datenquelle dar (die am häufigsten abgefragt wird). Die Tabelle enthält ungefähr fünf Millionen Zeilen. Bei den Datenänderungen handelt es sich überwiegend um UPDATEAnweisungen mit sehr gelegentlichen INSERTAnweisungen nach dem erstmaligen Laden der Daten. Ich habe mich dafür entschieden, die Daten nach zu gruppierendataPointId da Sie immer auswählen werden 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])
)

Die zweite Tabelle ist mit etwa 3,1 Milliarden Zeilen (entsprechend den Daten der letzten sechs Monate) deutlich größer. Daten, die älter als sechs Monate sind, werden gelöscht. ansonsten streng datenINSERT (~ 200 Zeilen / Sek., 720.000 Zeilen / Stunde, 17 Millionen Zeilen / Woche).

// 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])

)

Es wird erwartet, dass sich die Größe dieser Tabelle verdoppelt, wenn die Anzahl der verfolgten Datenpunktwerte auf 400 Zeilen / Sek. Ansteigt (sodass ein Erreichen von ~ 10 Milliarden nicht ausgeschlossen ist).

Die Fragen) (ja, ich stelle mehr als eine Frage ... sie hängen eng zusammen).

Ich verwende derzeit eine SQL Server 2008 R2 Standard Edition-Datenbank. Ich werde wahrscheinlich das Upgrade auf Enterprise Edition in Betracht ziehen, wenn mit Tabellenpartitionen das gewünschte Leistungsniveau erreicht werden kann (oder MongoDB, wenn mit SQL-Server die erforderlichen Leistungsniveaus nicht erreicht werden können). Ich hätte gerne Ihre Beiträge zu folgenden Themen:


1) Da ich brauche das zu berechnen min, maxund sumfür die vergangene Stunde (wie in now - 60 minutes). Was ist der beste Ansatz für die Verfolgung aktueller Daten:

  • Letzte Daten im Speicher des Datendienstes speichern. Schreiben Sie mit jedem Daten-UPDATE den berechneten Min / Max / Mittelwert aus.

  • Fragen Sie bei jeder UPDATE-Anweisung den aktuellen Verlauf aus der Verlaufstabelle ab (wirkt sich auf die nächste Frage aus?). Eine Abfrage würde auf die neuesten Daten für einen Datenpunktwert zugreifen und sollte nur die letzten Millionen Datensätze durchsuchen oder so?

  • Den letzten Verlauf in der DataPointValue-Zeile selbst speichern, um das Nachschlagen der Verlaufstabelle zu vermeiden? Vielleicht als begrenzte Zeichenfolge gespeichert und innerhalb des UPDATE-Prozesses verarbeitet?

  • Andere Option, die ich nicht in Betracht gezogen habe?


2) Für DataPointValueHistoryAbfragen gegen die Daten werden immer von dataPointIdund einer oder mehreren valueId. Die abgefragten Daten beziehen sich normalerweise auf den letzten Tag, die letzte Woche oder den letzten Monat, in einigen Fällen jedoch auch auf die gesamten sechs Monate.

Ich erstelle gerade einen Beispieldatensatz, um zu testen, ob das Clustering nach dataPointId / valueId / timeStamp oder timeStamp / dataPointId / valueId sinnvoller ist. Wenn jemand Erfahrung mit dem Umgang mit einem Tisch dieser Größe hat und bereit ist, seine Einsicht zu gewähren, wäre er dankbar. Ich neige zu letzterer Option, um eine Indexfragmentierung zu vermeiden, aber die Abfrageleistung ist entscheidend.

  • Cluster DataPointValueHistorynach dataPointId -> valueId -> timeStamp

  • Cluster DataPointValueHistoryvon timeStamp -> dataPointId -> valueId


3) Schließlich, wie oben erwähnt, halte ich es für sinnvoll, die DataPointValueHistoryTabelle zu partitionieren . Für Vorschläge zur optimalen Partitionierung der Verlaufsdaten sind wir sehr dankbar.

  • Wenn zuerst nach Zeitstempel geclustert wird, sollten die Daten nach Woche partitioniert werden (insgesamt 27 Partitionen). Die älteste Partition wird nach der 27. Woche gelöscht.

  • Wenn zuerst von dataPointId geclustert, denke ich, dass die Daten durch einen Modul der ID partitioniert werden sollten?

Da ich nur sehr wenig Erfahrung mit der Partitionierung von Tabellen habe, würde ich mich über Ihr Fachwissen freuen.

Calgary Coder
quelle
Haben Sie die Version dieser Frage auf StackOverflow gelöscht?
Taryn
@bluefeet - Ja, es wurde als "Off-Topic" markiert. Ich habe die SO-Frage gelöscht und hier neu erstellt (ich hätte wahrscheinlich darauf warten müssen, dass sie migriert wird).
Calgary Coder
Kein Problem, ich habe nur dafür gesorgt, dass wir keine Frage über Kreuz gepostet haben.
Taryn
In der Standard Edition können Sie die Daten weiterhin mit partitionierten Ansichten und mehreren Basistabellen partitionieren. Ich bin mir nicht sicher, ob du das in Betracht gezogen hast.
Jon Seigel
@Jon - Ja, ich habe manuelle Tabellenpartitionen in Betracht gezogen (diese spezielle Auswahl hängt davon ab, ob eine Enterprise-Lizenz verfügbar ist oder nicht ... wenn ja, warum sollte ich meine eigene Rolle spielen).
Calgary Coder

Antworten: