Schnelle Lesevorgänge, ohne den Preis für Schreibvorgänge zu zahlen


7

Wir haben eine große Tabelle nur mit Anhängen, die Finanztransaktionen enthält. Im Durchschnitt werden 1000 Transaktionen pro Minute eingefügt. Da es mittlerweile immer mehr Anwendungsfälle gibt, in denen wir diese Transaktionen tatsächlich lesen, suchen und aggregieren möchten, wären schnelle Lesevorgänge sehr hilfreich.

Wir möchten sehr schnelle Schreibvorgänge garantieren, und das Hinzufügen von Indizes, um einige der Lesevorgänge abzudecken, würde das Schreiben verlangsamen.

Die gute Nachricht ist, dass wir uns veraltete Daten leisten können. Ich habe überlegt, alle n Minuten eine Kopie der Daten in eine leseoptimierte Tabelle (mit Indizes) zu erstellen , was auch eine periodische Massenkopie ermöglicht (wodurch die Anzahl der Operationen begrenzt wird?).

Ich suche eine Meinung dazu, ob dies eine gültige Strategie ist. Wenn Sie dies für eine anständige Strategie halten, haben Sie Hinweise auf Implementierungsoptionen? Wenn nicht, welche Alternativen gibt es?


4
Was ist die Version und Edition von SQL Server? Ich denke, AlwaysON könnte hier eine Lösung sein, wenn ich Ihre Frage richtig lese.
Shanky

Haben Sie etwas dagegen, die Tabelle zu veröffentlichen und wo Sie Indizes möchten? Mit Transaktion meinen Sie, dass die Einfügung in eine SQL-Transaktion eingeschlossen ist oder dass es sich um eine "Finanztransaktion" handelt, die durch eine einzelne Zeile dargestellt wird.
Paparazzo

Antworten:


6

Für SQL Server 2014 und höher ist meine Empfehlung ziemlich radikal: Wechseln Sie zu einem Clustered Columnstore-Index. 1000 Datensätze / min liegen auch bei bescheidener Hardware im Bereich der Massenladefunktionen von Columnstores. Siehe Clustered Columnstore-Index: Optimierungen beim Laden von Daten - Minimale Protokollierung und Tuple Mover für Clustered Columnstore von SQL Server . Die Abfrageleistung eines gruppierten Spaltenspeichers ist aufgrund der inhärenten Vorteile der Spaltenspeicherung und Stapelverarbeitung erstaunlich. Dies gilt umso mehr für Zeitreihen (bei denen es sich wahrscheinlich um Ihre Daten handelt), da die Segmente sehr wahrscheinlich eliminiert werden .

In SQL Server 2016 gibt es einige spezifische Verbesserungen für Ihren Fall, siehe Echtzeit-Betriebsanalysen mithilfe der In-Memory-Technologie und Beschleunigung der Geschäftsanalysen mithilfe der In-Memory-Technologie .

Für SQL Server 2012 und früher empfehle ich ein Upgrade auf 2014 oder 2016.

In jedem Fall würde ich die Transaktionsreplikation aus zwei Gründen scheuen:

Beachten Sie auch, dass Protokollversand oder lesbare AlwaysOn-Sekundärdateien nur die Verarbeitung von Abfragen auslagern können, nicht jedoch die Schemaanforderungen (dh Indizes). Jeder Index, der für die Abfrage des Replikats erforderlich ist, muss in der ursprünglichen Datenbank erstellt werden, und der Preis wird zum Zeitpunkt des Schreibens bezahlt.

Natürlich nehme ich Sie Due Diligence und Ihr Schreiben hat sich nun optimiert, dh. Alle Hinweise im Leistungshandbuch zum Laden von Daten werden angewendet, und Ihr Upload ist umfangreich und wird nur minimal protokolliert.


4
Beachten Sie, dass dies Enterprise voraussetzt
Aaron Bertrand

Ich habe darüber gelesen und habe noch etwas zu lesen, und das
scheint gut zu

Für ein Budget können Sie Hadoop Hive Stream Ingest und Hive
Query

1
Aber am Ende des Tages sind 16 Einfügungen pro Sekunde kein Grund zur Sorge, dass "Indizes das Schreiben verlangsamen".
Remus Rusanu

2

Ohne auf die offensichtlichen Hardwaremöglichkeiten und HA-Lösungen einzugehen, würde ich in Betracht ziehen, eine "Staging-Tabelle" zu erstellen, die nur minimal indiziert ist, oder sogar einen Heap, in dem Sie eingehende Transaktionen mit maximaler Leistung auslagern können.

Ein geplanter / wiederkehrender Prozess könnte diese Daten dann asynchron in die Hauptfaktentabelle verschieben, die Indizes enthalten könnte, die für die Berichterstellung besser geeignet sind. Mit demselben Prozess können auch Aggregate in einer anderen Tabelle verwaltet werden, sodass Sie Berichte direkt auf diesen Aggregaten erstellen können. Der Schlüssel ist asynchron , daher würde ich keine Trigger oder indizierten Ansichten verwenden, sondern so etwas wie einen SQL Server-Agent-Job, der eine gespeicherte Prozedur immer wieder ausführt.

Vorteile:

  • Blitzschnelle Einfügungen (kaum Wartezeit beim Schreiben von Transaktionen)
  • Eine größere Anzahl von Zeilen, die pro Stapel in die Faktentabelle eingefügt werden, sollte eine bessere Schreibleistung bieten
  • Ermöglicht bessere / mehr Indizes für die Faktentabelle
  • Aggregierte Tabellen bieten eine ziemlich gute Berichtsleistung

Nachteile:

  • Die Staging-Tabelle ist möglicherweise für einen kurzen Zeitraum gesperrt, wenn sie vom asynchronen Prozess abgefragt wird.
  • Leichte Verzögerung vom Einfügen bis die Daten verfügbar sind.
  • Komplexität hinzugefügt

Oh, und wenn Sie mit SQL Server 2014/2016 Enterprise Edition arbeiten, befindet sich Ihre Staging-Tabelle möglicherweise im Arbeitsspeicher.


Berücksichtigen Sie für den asynchronen Prozess cdc, da es aus dem Transaktionsprotokoll ausgeführt wird, sodass Ihre Staging-Tabelle nicht
Andrew Bickerton,

2

Wenn es sich nur um eine einzelne Tabelle handelt, sollten Sie überlegen, ob eine zweite Kopie der Tabelle nur für Berichtszwecke verwendet werden soll. Ich habe hier eine zweiteilige Serie über meine Lösung geschrieben: Teil 1 | Teil 2 .

Im Wesentlichen haben Sie eine Tabelle, die eine Kopie Ihrer Transaktionstabelle darstellt, diese ist jedoch für Ihre Berichtsarbeitslast optimiert (als solche enthält sie möglicherweise nur eine Teilmenge von Spalten, eine Teilmenge von Zeilen, und ein Teil dieses Prozesses kann völlig anders erstellt werden Indizes für die gelesene Kopie der Tabelle - dies erhöht jedoch die Zeit für den Prozess.

Alle N Minuten, etwas weniger als das, was Ihre Definition von "veraltet" widerspiegelt, füllen Sie eine zweite Kopie dieser Tabelle (in einem anderen Schema oder mit einem anderen Namen) mit den aktuelleren Daten aus Ihrer Transaktionstabelle. Sobald es ausgefüllt ist, können Sie eine Transaktion starten, die Tabellen (Name oder Schema) austauschen und dann festschreiben. Die nächste Person, die die Daten aus der Kopie liest, erhält die frischeren Daten.

Wie lange das langsame Laden des Hintergrunds dauert, spielt keine Rolle, da Sie bereits eingeräumt haben, dass veraltete Daten in Ordnung sind. Sie müssen jedoch sicherstellen, dass Sie beiden Kopien Berechtigungen zuordnen, und Statistiken müssen möglicherweise auch Teil des Prozesses sein.


1

1000 Transaktionen pro Minute
= 16,67 / Sekunde
= 480.000 / 8 Std. Tag

16,67 / Sekunde ist nicht das schnelle. Ich bekomme über 100 / Sekunde auf einem normalen aktiven großen Tisch.

Wählen Sie Ihre PK oder mindestens einen Index aus, nach dem Sie die eingehenden Daten sortieren können, damit Sie eine minimale Fragmentierung dieses Index haben.

Wenn Sie Datensätze speichern können, um 100 oder 1000 gleichzeitig einzufügen, und diese sortiert einfügen. Eine Einfügung von 100 Datensätzen ist viel schneller als 100 Einfügungen von jeweils einem Datensatz. Lassen Sie den Timer mindestens alle x Sekunden einfügen.

Wählen Sie in den anderen Indizes nur das aus, was Sie benötigen. Geben Sie ihnen einen Füllfaktor von 50. Sie werden erstaunt sein, wie viel langsamer die Fragmentierung stattfindet, wenn Sie etwas Platz mit einem Füllfaktor lassen.

Führen Sie die Indexpflege täglich durch.

Ja, Sie müssen vielleicht exotischer werden, aber 1000 / Minute ist nicht so groß. Selbst wenn Sie ein exotischeres Indexdesign erhalten, ist eine minimierte Fragmentierung immer noch eine gute Sache.


1

Ich denke, Daniels Antwort ist wahrscheinlich besser als meine, aber nur um Ihnen die grundlegenden Alternativen zu geben:

Transaktionsreplikation mit nur dieser replizierten Tabelle auf einen anderen Server.

Vorteile:

  • Sofort lesbare Daten
  • Lesesperren blockieren nur den replizierten Server
  • Die Transaktionsreplikation wird durch Ihr Transaktionsprotokoll gelesen, wobei ein Agent alle Transaktionen liest und ein Skript generiert, das an die Verteilungsdatenbank gesendet wird

Nachteile:

  • Fügt alle Daten zeilenweise in Ihre replizierte Datenbank ein (langsam)
  • Benötigt eine neue Instanz / einen neuen Server
  • Erfordert viel mehr Wartungs- / DBA-Zeit sowie zusätzliche Schritte zur Wiederherstellung (Generieren eines neuen Snapshots usw.)
  • Zusätzlicher Aufwand für die Pflege der Verteilungsdatenbank
  • Die Netzwerklatenz führt zu einer Replikationslatenz, wodurch die replizierte Datenbank leicht veraltet ist

Protokollversand (Die sekundäre Datenbank, die Transaktionsprotokolle empfängt, sollte in Bereitschaft sein, damit Lesevorgänge möglich sind.)

Vorteile:

  • Alle Tabellen, die erfolgreich in einer neuen Instanz wiederhergestellt wurden, ermöglichen es Ihren Abfragen, jede Tabelle zu treffen
  • Keine Auswirkungen auf den Primärserver

Nachteile:

  • Die Größe der Zieldatenbank entspricht immer der Hauptdatenbank
  • Netzwerkverkehr, wenn außerhalb des Standorts gesendet
  • Benutzer werden gestartet, wenn die Protokolle wiederhergestellt werden

Wie oben in einer anderen Antwort angegeben, kann der Protokollversand diesen Zweck nicht wirklich erfüllen. Die ausgelieferte Tabelle hat das gleiche Schema wie die ursprüngliche Tabelle, und das ursprüngliche Poster möchte unterschiedliche Indizes in seiner "veralteten" Tabelle. Für den Protokollversand müssten sich diese Indizes auch in der "Live" -Tabelle befinden.
Ross Presser

1

Müssen Sie dies direkt in der Datenbank behandeln? Da Sie mit leicht veralteten Daten einverstanden sind, neige ich dazu, einzelne Abfrageergebnisse und nicht die gesamte Tabelle in einer Ebene wie memcached oder redis zwischenzuspeichern .

Dies ist ein ziemlich normaler Ansatz in der Entwicklung von Webanwendungen. Der Hauptnachteil besteht darin, dass Entwicklungsaufwand für die Anwendung erforderlich ist, der für Ihre spezielle Situation möglicherweise nicht funktioniert (wir wissen jedoch nicht, was Sie uns mitgeteilt haben).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.