SQL Server 2008 - Partitionierung und Clustered-Indizes

16

Lassen Sie mich vorab sagen, dass ich nicht die vollständige Kontrolle über mein DB-Design habe, sodass viele Aspekte des aktuellen Systems für die Zwecke dieses Szenarios nicht geändert werden können .

Kommentare darüber, wie wir Aspekte des Designs überdenken sollten, sind wahrscheinlich korrekt, aber nicht hilfreich :)

Ich habe eine sehr große Tabelle, ungefähr 150 Felder breit und ungefähr 600m Reihen, die eine große Anzahl von Prozessen antreibt. Dies befindet sich in einer Data-Warehouse-Situation, sodass wir keine Aktualisierungen / Einfügungen außerhalb des geplanten Ladeprozesses haben und daher stark indiziert sind.

Es wurde die Entscheidung getroffen, diese Tabelle zu partitionieren, und ich habe einige Bedenken hinsichtlich der Indizierung einer partitionierten Tabelle. Ich habe keine Erfahrung mit Partitionierung, daher sind alle Eingaben oder Links willkommen. Ich konnte auf BOL oder msdn nicht genau finden, wonach ich suche.

Derzeit gruppieren wir uns auf einem Feld, das wir aufrufen. IncidentKeyDies ist ein varchar(50)und kein eindeutiges Feld - wir könnten zwischen 1 und 100 Datensätze mit demselben haben IK(bitte keine Kommentare). Wir erhalten häufig neue Daten in alten IncidentKeyDatensätzen, sodass diese auch nicht sequenziell sind.

Ich verstehe, dass ich mein Partitionsfeld IncidentDatein meinen gruppierten Indexschlüssel aufnehmen muss, damit die Partition ordnungsgemäß funktioniert. Ich denke es wäre IncidentKey, IncidentDate.

Die Frage ist, wie die Mechanik eines Clustered-Index für einen Schlüssel mit zwei Teilen in einer partitionierten Tabelle funktioniert, wenn ein Datensatz in einer "neuen" Partition vor einem Datensatz in einer "alten" Partition im Clustered-Index stehen soll.

Zum Beispiel habe ich 5 Datensätze:

IncidentKey    Date

ABC123        1/1/2010
ABC123        7/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010
XYZ999        7/1/2010

Wenn ich einen neuen Datensatz bekommen für ABC123, 2/1/2011sie müssen in der Clustered - Index sein VOR XYZ999, 1/1/2010 . Wie funktioniert das?

Ich gehe von Fragmentierung und Zeigern aus, kann jedoch keine Informationen zum physischen Speicher und zur Konfiguration von nicht partitionierten Clustered-Indizes für partitionierte Tabellen mit zweigeteilten Schlüsseln finden.

JNK
quelle
Warum wurde die Entscheidung getroffen, die Tabelle zu partitionieren? Was sind die erwarteten Vorteile der Partitionierung?
Remus Rusanu
@ Remus - Ich mache es eigentlich als Test, also werden wir eine partitionierte und eine nicht partitionierte Version haben. Der erwartete Vorteil sind kürzere Ladezeiten und kürzere Indexerstellungszeiten. Wir führen monatliche ETL-Vorgänge durch, die ungefähr eine Woche dauern, und hoffen, dass dies diese Zeit erheblich verkürzen wird. Wir haben auch einen Einsatz von ca. 3 TB, den wir hoffentlich damit reduzieren können.
JNK

Antworten:

18

Eine partitionierte Tabelle ist eigentlich eher eine Sammlung einzelner Tabellen, die zusammengefügt werden. Beispiel für Clustering nach IncidentKeyund Partition nach IncidentDate: Die Partitionierungsfunktion teilt die Tabellen in zwei Partitionen auf, sodass sich der 1.1.2010 in Partition 1 und der 1.1.2010 in Partition 2 befindet. Die Daten werden wie folgt auf der Festplatte abgelegt:

Partition 1:
IncidentKey    Date
ABC123        1/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010

Partition 2:
IncidentKey    Date
ABC123        7/1/2010
XYZ999        7/1/2010

Auf einer niedrigen Ebene gibt es zwei unterschiedliche Rowsets. Ist der Abfrageprozessor, der die Illusion einer einzelnen Tabelle erzeugt, indem er Pläne erstellt, die alle Rowsets gleichzeitig suchen, scannen und aktualisieren .

Jede Zeile in einem nicht gruppierten Index hat beispielsweise den gruppierten Indexschlüssel, dem sie entspricht ABC123,7/1/2010. Da der Clustered-Indexschlüssel immer die Partitionierungsschlüsselspalte enthält, weiß das Modul immer, in welcher Partition (Rowset) des Clustered-Index nach diesem Wert gesucht werden soll (in diesem Fall in Partition 2).

Wenn Sie sich nun mit Partitionierung beschäftigen, müssen Sie prüfen, ob Ihre NC-Indizes ausgerichtet (NC-Index ist genauso wie der Clustered-Index partitioniert) oder nicht ausgerichtet (NC-Index ist nicht partitioniert oder anders als Clustered-Index partitioniert) sind. . Nicht ausgerichtete Indizes sind flexibler, haben jedoch einige Nachteile:

  • Nicht ausgerichtete Indizes benötigen für bestimmte Abfragepläne viel Speicher
  • Nicht ausgerichtete Indizes verhindern effiziente Partitionswechselvorgänge

Die Verwendung von ausgerichteten Indizes behebt diese Probleme, bringt jedoch eine Reihe von Problemen mit sich, da diese physische Speicherentwurfsoption das Datenmodell beeinträchtigt:

  • Ausgerichtete Indizes bedeuten, dass keine eindeutigen Einschränkungen mehr erstellt / erzwungen werden können (mit Ausnahme der Partitionierungsspalte).
  • Alle Fremdschlüssel, die auf die partitionierte Tabelle verweisen, müssen den Partitionierungsschlüssel in der Relation enthalten (da der Partitionierungsschlüssel aufgrund der Ausrichtung in jedem Index vorhanden ist), und dies erfordert wiederum, dass alle Tabellen, die auf die partitionierte Tabelle verweisen, den Spaltenwert des Partitionierungsschlüssels enthalten. Denken Sie an Orders-> OrderDetails. Wenn Orders OrderID haben, aber durch OrderDate partitioniert sind, muss OrderDetails nicht nur OrderID, sondern auch OrderDate enthalten, um die Fremdschlüsseleinschränkung ordnungsgemäß zu deklarieren.

Diese Effekte wurden zu Beginn eines Projekts, in dem Partitionierung implementiert wird, selten genannt, sind jedoch vorhanden und haben schwerwiegende Folgen.

Wenn Sie der Meinung sind, dass ausgerichtete Indizes ein seltener oder extremer Fall sind, sollten Sie Folgendes berücksichtigen: In vielen Fällen ist der Eckpfeiler von ETL- und Partitionierungslösungen das schnelle Einschalten von Staging-Tabellen. Einschaltvorgänge erfordern ausgerichtete Indizes.

Noch eine Sache: Alle meine Argumente zu Fremdschlüsseln und dem Ripple-Effekt des Hinzufügens des Partitionierungsspaltenwerts zu anderen Tabellen gelten auch für Joins .

Remus Rusanu
quelle
Perfekt, genau das habe ich gesucht. Wir müssen ausgerichtete Indizes b / c verwenden. Das Austauschen ist ein Teil der Verlosung für das, was wir damit machen wollen. Wir führen auch eine TON von Aggregatfunktionen durch IncidentKey, die auf diesem Gebiet gruppiert sind, was meiner Meinung nach ernsthaft hinderlich sein wird. Ich schätze jedes Detail!
JNK
Normalerweise überwiegen die Vorteile von Partitionswechselvorgängen alle Probleme.
Remus Rusanu
Das ist unsere Hoffnung, wir werden es bald sehen!
JNK
9

Wenn ein Clustered-Index mehrere Partitionen hat, hat jede Partition eine B-Baumstruktur, die die Daten für diese bestimmte Partition enthält. Wenn ein Clustered-Index beispielsweise vier Partitionen enthält, gibt es vier B-Tree-Strukturen. eine in jeder Partition. Ref. Clustered-Index-Strukturen

Spezielle Richtlinien für partitionierte Indizes

Sie können bestimmte Partitionen eines partitionierten Index neu erstellen.

z.B

ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5;
GO
Mitch Weizen
quelle
+1 Für den Link hatte ich die speziellen Richtlinien gelesen, aber diesen Absatz verpasst. Anschlussfrage - Wir führen eine Menge Aggregationen auf dem IncidentKeyFeld durch. Glauben Sie, dass dies die Leistung nachteilig beeinflussen würde (mir ist klar, dass ich noch Tests durchführen muss)?
JNK
Ich kenne nicht alle Ihre spezifischen Umstände, aber es fällt mir auf, dass Sie besser nach IncidentDate partitionieren sollten.
Mitch Wheat
Wir partitionieren nach dem Datum, aber der Clustered Key ist aktiviert IncidentKey- wir machen eine Menge Joins, und es ist eine Art institutionelle Sache, die wir zum Clustering verwenden. Ich teste einen alternativen Schlüssel, aber im Moment muss ich diesen verwenden.
JNK