SQL-Großtabellendesign

17

Ich habe eine allgemeine Frage zum Design von SQL Server 2008-Tabellen. Wir haben derzeit einen Tisch mit mehr als 600 GB und wächst mit etwa 3 GB pro Tag. Diese Tabelle verfügt über die entsprechenden Unabhängigkeitswerte, wird jedoch aufgrund ihrer Größe zu einem wichtigen Absturz beim Ausführen von Abfragen. Die Frage ist, ob ich die Tabelle nach Jahr und Monat in mehrere Tabellen aufteilen soll (dies würde dazu passen, wie andere Abteilungen ihre großen Datenmengen aufteilen) oder ob wir die in SQL Server integrierte Partitionierung nutzen sollen. Es scheint, dass die Verwendung der Partitionierung weniger Codeänderungen erfordern würde. Nach dem, was ich beim Partitionieren gelesen habe, fragen Sie immer noch nur eine Tabelle ab, und der Server verwaltet, wie die Daten abgerufen werden. Wenn wir uns für die Route mit mehreren Tabellen entschieden hätten, müssten wir das Abrufen von Daten aus mehreren Tabellen behandeln.

HunterX3
quelle
1
Müssen Optimierungen vorgenommen werden: zu breite Datentypen, überlappende oder nicht verwendete Indizes usw.?
11.
Möglicherweise habe ich noch nicht nach anderen Optimierungen gesucht. Haben Sie Empfehlungen?
HunterX3

Antworten:

11

"Diese Tabelle verfügt über die entsprechenden Independence-Werte, wird jedoch zum Hauptproblem beim Ausführen von Abfragen."

Das Partitionieren allein trägt nicht zur Abfrageleistung bei, es sei denn, SQL Server kann beim Ausführen einer Abfrage Partitionen entfernen. Ihre WHERE-Klausel muss mit der Art und Weise übereinstimmen, in der Sie partitionieren. Wir können nur ein Feld als Partitionierungsfeld verwenden. Wenn dieses Feld also nicht in Ihrer WHERE-Klausel enthalten ist, durchsuchen Sie wahrscheinlich trotzdem die gesamte Tabelle, obwohl Sie Partitionen haben.

"und nur wegen seiner Größe."

Partitionierung kann bestimmte Wartungsvorgänge vereinfachen, es gibt jedoch noch einige Dinge, die wir nicht partitionweise ausführen können. Wenn die Indexpflege und die Aktualisierung der Statistiken zu Problemen führen, sollten Sie das Design besser in eine Archivtabelle und eine live aktualisierte Tabelle aufteilen. Wenn Sie regelmäßig Daten aus der Live-Tabelle in die Archivtabelle verschieben müssen, erstellen Sie die Indizes mit einem Füllfaktor von 100% neu, aktualisieren die Statistiken mit einem vollständigen Scan und setzen die Dateigruppe dann auf schreibgeschützt. Die Partitionierung kann beim Laden von Archivtabellen hilfreich sein, die Partitionierung der aktiven Tabelle jedoch möglicherweise nicht. (Ich werfe hier einige fortgeschrittene Konzepte raus, als ob es schnell und einfach wäre, aber ich skizziere hier nur einige Hintergründe.)

"Es scheint, dass die Verwendung der Partitionierung weniger Codeänderungen erfordern würde."

Sorta kinda - auf den ersten Blick sieht es so aus, aber je mehr Sie sich damit beschäftigen, desto mehr Optionen stehen Ihnen zur Verfügung, wie z. B. partitionierte Ansichten. Sie können die vorhandene Tabelle umbenennen, eine Ansicht an ihrer Stelle platzieren und dann Ihre eigenen Änderungen an den zugrunde liegenden Tabellen vornehmen (und mehrere Tabellen hinzufügen), ohne Ihre App zu ändern.

Ich habe hier mehr über die Fallstricke der Partitionierung geschrieben:

http://www.brentozar.com/archive/2008/06/sql-server-partitioning-not-the-answer-to-everything/

Brent Ozar
quelle
3
Das Lieblingszitat aus diesem Artikel ist definitiv "Partitionsfunktionen und -schemata sind leicht falsch zu entwerfen."
Mark Storey-Smith
7

Eine isolierte Partitionierung ist möglicherweise ausreichend, aber möglicherweise erzielen Sie bessere Ergebnisse, wenn Sie sie mit partitionierten Ansichten und mehreren Tabellen kombinieren. Es hängt sehr stark vom Muster der Abfrage und des Wachstums ab.

Die aktuelle Einschränkung bei der Partitionierung besteht darin, dass Spaltenstatistiken nur in einer Tabelle und nicht auf Partitionsebene verwaltet werden. Wenn Sie ein Abfragemuster haben, das von genaueren Statistiken profitiert, kann die Kombination von Tabellenpartitionierung mit partitionierten Ansichten zu erheblichen Leistungsvorteilen führen.

Wenn die Art Ihrer Daten von Monat zu Monat, von Jahr zu Jahr variiert, können auch partitionierte Ansichten hilfreich sein. Stellen Sie sich einen Einzelhändler vor, der seine Produktlinien ständig ändert, so dass das Product.ProductId nur eine geringe Konsistenz aufweist und von Jahr zu Jahr verwendet wird. Mit einer einzelnen Auftrags- / Auftragsdetailtabelle und daher einem einzelnen Statistikhistogramm bieten die Statistiken dem Abfrageoptimierer nur wenig. Eine Tabelle pro Jahr (Order_2010, Order_2011, OrderLine_2010, OrderLine_2011), die nach Monat partitioniert und mit partitionierten Ansichten (Order, OrderLine) kombiniert ist, bietet dem Optimierer detailliertere und potenziell nützliche Statistiken.

Sie können die Tabellenpartitionierung mit vergleichsweise geringem Aufwand einführen. Beginnen Sie also dort, messen Sie die Auswirkung und bewerten Sie später, ob partitionierte Ansichten den zusätzlichen Aufwand wert wären.

Kimberly Tripp hat zahlreiche Leitfäden und Whitepapers zum Thema Partitionierung veröffentlicht , die im Allgemeinen als erforderlich erachtet werden, um das Thema zu lesen. Kendra Little hat auch gutes Material und eine nützliche Referenzliste anderer Artikel

Leistung ist in der Regel der Hauptgrund, warum die Leute auf Partitionierung setzen. Persönlich sehe ich die Verbesserung der Wiederherstellungszeit als gleichwertigen oder größeren Vorteil einer VLDB an. Nehmen Sie sich etwas Zeit, um sich mit der Teilverfügbarkeit und der schrittweisen Wiederherstellung vertraut zu machen, bevor Sie beginnen, da dies die Vorgehensweise beeinflussen kann.

Wenn Sie den nicht idealen, aber nicht ungewöhnlichen Prozess zum Senden von Sicherungen über das Netzwerk haben, wird möglicherweise eine Wiederherstellungszeit von 3 Stunden für Ihre aktuellen 600 GB angestrebt. In einem Jahr, in dem Sie 1,5 TB überschritten haben, haben Sie ein Problem.

Mark Storey-Smith
quelle
1
+1 Für "Spaltenstatistiken werden nur an einem Tisch gepflegt" und ich wünschte, ich könnte noch einmal +1 für Links zu Kimberly und Kendra geben.
Matt M
1

Wie Sie sagten, haben Sie hier zwei Möglichkeiten:

  1. Verwenden Sie mehrere Tabellen
  2. Partitionierung verwenden

Mit 1 können Sie eine ANSICHT erstellen, die alle diese Tabellen zusammenfasst, und sie einfach aktualisieren, um neu erstellte Tabellen einzuschließen. Ich betrachte dies als eine Möglichkeit, die Partitionierung zu emulieren. Zu den Vorteilen dieser Methode gehört, dass keine Enterprise Edition von SQL Server erforderlich ist.

Mit 2 können Sie Ihre Indizes an Ihren Partitionen ausrichten und Ihre Partitionen an verschiedenen Speichern ausrichten. Nachdem Sie die Partitionsfunktion und das Partitionsschema eingerichtet haben, erfolgt dies für Sie, wenn Sie Partitionen teilen oder zusammenführen. Zu den Vorteilen dieser Methode gehört, dass Datensätze nicht manuell in eine neue Tabelle verschoben werden müssen. Da die Partitionsfunktion und das Partitionsschema dies für Sie erledigen. Wie Sie bereits sagten, sind für den Zugriff auf die Daten kaum oder keine Codeänderungen erforderlich.

Wenn Sie Enterprise Edition haben, würde ich Partitionierung auf jeden Fall einen Blick geben. Trotz der Komplexität ist es nicht so schlimm. Wenn nicht, ist die Partitionierung nicht einmal eine Option für Sie.

Partitionierte Tabellen erstellen

Partitionierte Tabellen ändern

Entwerfen von Partitionen zum Verwalten von Teilmengen von Daten

Hoffe das hilft,

Matt

Matt M
quelle
0

Aufgrund Ihrer Frage scheinen Sie historische Daten (Protokolle) zu speichern, und Ihre Einschränkung scheint auf die Abfragegeschwindigkeit und nicht auf Speicherplatzprobleme zurückzuführen zu sein. Für mich hilft Partition nicht.

Wenn Sie sagen, Sie haben richtige Indizes, enthält es einen Index für das Datumsfeld? Ich hatte mit Postgres gute Ergebnisse mit dem Index auf Trunc (Zeitstempel, Tag). Sie müssen dann sicherstellen, dass alle Abfragen am Tag vor anderen Manipulationen ausgewählt werden. Beachten Sie, dass ein Zeitstempel mit Zeitzonenfeld nicht indizierbar ist (da er sich je nach Zeitzone "verschiebt"), sodass Sie einen "festen" Zeitstempel für die Indizierung benötigen.

gb.
quelle
Unsere Unabhängigkeit basiert darauf, welche Felder am häufigsten genutzt werden. Wir haben 1 Clustered und 2 Non-Clustered, beide scheinen wie angekündigt zu funktionieren. Ich denke, es ist eher die Größe, die das Problem ist.
HunterX3