Ratschläge, wie Ausführungszeiten einer „Pivot-Abfrage“ auf eine Milliarde Zeilen Tabelle, skalieren und verbessern eine Million pro Tag zu erhöhen

StackOverflow https://stackoverflow.com/questions/1002086

Frage

Unser Unternehmen ist die Entwicklung eine interne Projekttextdatei zu analysieren. Diese Textdateien werden von Metadaten zusammen, die regelmäßig expresions extrahiert werden. Zehn Computer 24/7 Parsen der Textdateien und Zuführen eine High-End-Intel-Xeon-SQL Server 2005-Datenbank mit dem extrahierten Metadaten.

Die vereinfachte Datenbankschema sieht wie folgt aus:

Items

| Id | Name   |
|----|--------|
| 1  | Sample |
Items_Attributes

| ItemId | AttributeId |
|--------|-------------|
| 1      | 1           |
| 1      | 2           |
Attributes

| Id | AttributeTypeId | Value |
|----|-----------------|-------|
| 1  | 1               | 500mB |
| 2  | 2               | 1.0.0 |
AttributeTypes

| Id | Name    |
|----|---------|
| 1  | Size    |
| 2  | Version |

Es gibt viele verschiedene Arten von Textdateien mit unterschiedlichen Metadaten im Innern. Für jede Textdatei wir ein Item und für jeden extrahierten Metadaten Wert haben wir eine Attribute.

Items_Attributes allow us to avoid duplicate Attribute values which avoids database size to increase x^10.

This particular schema allows us to dynamically add new regular expressions and to obtain new metadata from new processed files no matter which internal structure they have.

Additionally this allow us to filter the data and to obtain dynamic reports based on the user criteria. We are filtering by Attribute and then pivoting the resultset (http://msdn.microsoft.com/en-us/library/ms177410.aspx). So this example pseudo-sql query

SELECT FROM Items WHERE Size = @A AND Version = @B

would return a pivoted table like this

| ItemName | Size  | Version |
|----------|-------|---------|
| Sample   | 500mB | 1.0.0   |

The application has been running for months and performance decreased terribly at the point is no longer usable. Reports should take no more than 2 seconds and Items_Attributes Tabelle erhöht durchschnittlich 10 Millionen Zeilen pro Woche. Alles ist korrekt indiziert und wir haben schwere Zeit mit der Analyse und Abfrageausführungspläne zu optimieren.

Also meine Frage ist, wie würden Sie dies, um maßstab Bericht Ausführungszeiten zu verringern?

Wir kamen mit diesen möglichen Lösungen:

  • Kaufen Sie mehr Hardware und das Setup ein SQL Server-Cluster. (Wir brauchen Beratung über die richtige „Clustering“ -Strategie)
  • Verwenden Sie einen Schlüssel / Wert-Datenbank wie HBase (wir wissen nicht wirklich, wenn würde unser Problem lösen)
  • Verwenden Sie ein ODBMS eher als ein RDBMS (wir haben db4o in Erwägung gezogen)
  • Bewegen Sie unsere Software in die Cloud (wir haben null Erfahrung)
  • Statisch Berichte zur Laufzeit generieren. (Wir wollen nicht wirklich)
  • Statische indizierte Sichten für gemeinsame Berichte (Leistung ist fast das gleiche)
  • De-normalisieren Schema (einige unserer Berichte beinhalten in einer einzigen Abfrage zu 50 Tabellen oben)
War es hilfreich?

Lösung

Vielleicht ist dieses Whitepaper von SQL Server CAT Team auf die Tücken der Entity-Attribute-Value-Datenbank-Modell kann helfen: http://sqlcat.com/whitepapers/archive/2008/09/03/best-practices- für semantische Datenmodellierung-for-Performance-and-scalability.aspx

Andere Tipps

würde ich zu veröffentlichen genaue Tabellen Metadaten (zusammen mit Indexierung), die genauen Abfragetext und den Ausführungsplan starten.

Mit Ihnen aktuelle Tabellenlayout die Abfrage wie folgt aus:

SELECT FROM Items WHERE Size = @A AND Version = @B

kann nicht profitieren einen zusammengesetzten Index auf (Size, Version) verwenden, da es unmöglich ist, einen solchen Index zu bauen.

Sie können nicht einmal eine indizierte Sicht bauen, da es sich um eine Selbstverknüpfung auf attributes enthalten würde.

Wahrscheinlich die beste Entscheidung wäre, die Tabelle wie folgt denormalize:

id  name  size  version

und einen Index für (size, version) erstellen

Arbeitete mit solchen Schemata viel Zeit. Sie führen nie gut. Das Beste ist, um nur die Daten zu speichern, wie Sie es brauchen, in der Form:

| ItemName | Größe | Version | | ---------- | ------- | --------- | | Probe | 500MB | 1.0.0 |

Dann ziehen Sie an; t drehen müssen. Und BTW, bitte rufen Sie nicht Ihr ursprüngliches EAV-Schema „normalisiert.“ - nicht normalisiert

scheint mir, wie die Ausstellung einige OLAP-Abfragen in einer Datenbank für OLTP-Transaktionen optimiert. Keine Details zu kennen, würde ich empfehlen, einen separaten „Datawarehouse“ Aufbau für die Art von Abfragen optimieren Sie tun. Das würde bedeuten, Daten (wenn möglich), Denormalisierung aggregieren und auch eine Datenbank mit, die 1 Tag alt oder so ist. Sie würden die Daten jeden Tag inkrementell aktualisieren oder zu einem beliebigen Intervall, das Sie mögen.

Bitte senden Sie genaue DDL und Indizes, wenn Sie Indizes für die ID-Spalten haben dann Ihre Abfrage in einem Scan führen

anstelle von etwas wie diese

SELECT FROM Items WHERE Size = @A AND Version = @B

Sie müssen dies tun,

SELECT FROM Items WHERE ID = 1

Mit anderen Worten müssen Sie die Textwerte greifen, finden die IDs, die Sie indizieren auf und verwenden Sie dann, dass als Abfrageergebnisse zurück, anstatt

Wahrscheinlich auch eine gute Idee, bei Partitionierungsfunktion zu suchen, Ihre Daten zu verteilen

Clustering wird für die Verfügbarkeit nicht auf die Leistung erfolgen, wenn ein Knoten (den aktiven Cluster) stirbt, der andere Knoten (das passive Cluster) wird .... aktiver geworden Natürlich gibt es auch aktiv aktiv Clustering, aber das ist eine andere Geschichte

Eine kurzfristige Korrektur kann horizontale Partitionierung . Ich gehe davon aus Ihrer größten Tabelle Items_Attributes ist. Sie können diese Tabelle horizontal unterteilen, jede Partition auf einem separaten Dateigruppe auf einem separaten Datenträger-Controller setzen.

Das ist vorausgesetzt, Sie nicht sofort in allen ItemIds zu berichten versuchen.

Sie erwähnen 50 Tabellen in einer einzigen Abfrage. Während SQL Server in einer einzigen, monolithischen Abfrage zu 256 Tabellen unterstützt auf, diesen Ansatz verringert die Chancen des Optimierers einen effizienten Plan zu erzeugen.

Wenn Sie auf das Schema fest gebunden sind, wie es steht, betrachten Sie Ihre Berichtsabfragen brechen in eine Reihe von Schritten, die ihre Ergebnisse in temporäre (#) Tabellen materialisieren. Dieser Ansatz ermöglicht es Ihnen, die selektivsten Teile der Abfrage in Isolation durchzuführen, und kann meiner Erfahrung bieten große Performance-Gewinne. Die Abfragen sind in der Regel besser verwaltbar zu.

Auch (ein bisschen weit hergeholt, hat diese) Sie sagen nicht die SQL Server-Version Sie sind auf; aber wenn Sie auf SQL 2005 sind, ging es um die Anzahl der Tabellen in Ihren Berichten gegeben und das Volumen der Daten, ist es wert, dass Ihr SQL Server auf mindestens SP2 gepatcht wird.

ich auf einem ETL-Projekt arbeitete mit Hilfe von Tabellen mit rowcounts in den Hunderten von Millionen, wo wir, dass die Abfrage-Optimierer in SQL 2005 RTM / SP1 gefunden können nicht konsequent effiziente Pläne für Abfragen produzieren mehr als 5 Tabellen verknüpft werden, wo ein oder mehrere der die Tische waren diese Größenordnung. Dieses Problem wurde in SP2 behoben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top