An welchem ​​Punkt sollte ich eine sehr große, aber einfache Tabelle teilen oder partitionieren?

8

Unsere Website enthält einige große, aber einfache (INT, INT, DATE) Tabellen für Statistiken. Jede Tabelle hat bis zu 300.000.000 Zeilen und wird von Tag zu Tag größer.

Der Hosting-Anbieter hat vorgeschlagen, die Tabellen zu teilen oder zu partitionieren, und ich habe diese Empfehlung bei zahlreichen Gelegenheiten an anderer Stelle gesehen.

Jedoch...

Ich habe Probleme, diesen Rat mit der angegebenen maximalen Kapazität für SQL Server in Einklang zu bringen - einer Datenbankgröße von 524.272 Terabyte, wobei Tabellenzeilen nur durch "verfügbaren Speicher" begrenzt sind.

Basierend auf diesen Zahlen könnte die oben beschriebene Tabelle leicht Zentillionen von Reihen haben (10 hoch 303).

Ah ha könnte man sagen, es gibt einen Unterschied zwischen FÄHIGKEIT und LEISTUNG.

In praktisch jeder Frage zur SQL Server-Leistung lautet die Antwort jedoch "Es hängt vom Tabellen- und Abfragedesign ab".

Deshalb stelle ich diese Frage. Das Tischdesign könnte nicht einfacher sein. Auch die Abfragen, bei denen es sich um einfache Zählvorgänge (*) handelt, konnten nicht auf einem indizierten ID-Feld basieren.

Martin Hansen Lennox
quelle
Das Partitionieren von Tabellen ist etwas, das Sie in Ihrem Datenbankdesign planen, bevor Sie Daten vorzugsweise tatsächlich schreiben. Es ist viel schwieriger und langwieriger, dies nachträglich zu tun.
1
Es hängt mehr von Ihrem Szenario ab: Ist die Leistung in Ordnung? Können Sie einige Daten archivieren? Sind Tabellen so groß, um effizient zu sichern / wiederherzustellen? Sind sie komprimiert? Es wäre gut gewesen, vom ersten Tag an zu partitionieren, aber der nächstbeste Tag ist heute, wenn Sie sich Sorgen über die zukünftige Leistung machen, wenn Sie Best Practices befolgen möchten.
LowlyDBA
2
Ich denke, mit dieser Datenmenge müssen Sie Ihre Datenbank auf Architekturebene, OLTP-Datenbank und OLAP-Datenbank aufteilen. Ihre Anwendungsdatenbank "OLTP" sollte nur die für Anwendung und Geschäft erforderlichen Mindestdaten enthalten, der Rest sollte in Daten gespeichert werden Lager "OLAP". Was die Frage How To Decide if You Should Use Table Partitioning
betrifft,
3
Leistung ist niemals nur die Tatsache, dass ein Tisch groß ist. In der Tat ist das, was für viele groß ist, für einige klein. Verstehen Sie, welche Vorgänge durch Partitionierung schneller und welche langsamer ausgeführt werden. Partitionierung ist kein schnellerer Wechsel. Es ist ein meist langsamerer Schalter und einige Dinge werden blendend schnell.
usr
4
Ich kann das MCM-Schulungsvideo zur Partitionierung von Kimberly Tripp nur empfehlen .
Paul White 9

Antworten:

10

Es gibt einen Grund, warum der allgemeine Rat lautet, dass er vom Tischdesign und den Abfragen abhängt. Meine Antwort auf Ihren anderen Beitrag auf Stack Exchange sagt das auch. Die Aussage "Abfragen, bei denen es sich um einfache Zähloperationen (*) handelt, die auf einem indizierten ID-Feld basieren" liefert nicht viele Informationen, da nichts über die Kardinalität der betrachteten Zeilenmenge aussagt. Dinge, die Sie tun können, um die (derzeit wahrgenommenen) Probleme zu mildern, sind:

  1. Partitionierung. Insbesondere scheinen Ihre Daten Daten vom Protokollierungstyp zu sein. Ich vermute, dass Sie Statistiken nach Zeiteinheiten abrufen möchten (z. B. "Widgets pro Tag" oder "Whozits pro Stunde"). Partitionieren Sie nach Ihrem Quantum (dh Tage oder Stunden in den vorherigen Beispielen) und verschieben Sie Partitionen gelegentlich in schreibgeschützte Dateigruppen

  2. Wenn die Daten einmal geschrieben werden, sollten Sie in Betracht ziehen, die Daten vorab zu aggregieren, sobald der Zeitraum nicht mehr aktiv ist. Das heißt, warum muss ich immer wieder zählen, wie viele Ereignisse an einem Tag vor drei Jahren passiert sind, wenn sich diese Daten niemals ändern werden? Wenn der Tag vorbei ist, zählen Sie alles an diesem Tag, lagern Sie es woanders und zählen Sie es nie wieder. Wenn Sie die detaillierten Daten nie benötigen (dh nur Aggregationen durchführen), sollten Sie sie löschen, nachdem Sie sie gezählt haben. Wenn Sie diese Idee umsetzen, können Sie mit gefilterten Indizes, die nur den "aktiven" Zeitraum abdecken, noch cleverer werden. Dadurch werden Ihre Abfragen schneller, da sie nicht die überwiegende Mehrheit Ihrer Daten abdecken

Aber, wie mein Rat im anderen Beitrag andeutet, ist der einzige Weg, den Sie sicher wissen werden, es mit einer angemessenen Datenmenge zu laden und auszuprobieren. Wir können hier nur sagen, was im allgemeinen Fall wahrscheinlich funktionieren wird. Ohne die Besonderheiten Ihrer Hardware, Ihrer Daten und Ihrer Fragen können wir nur raten. Und Sie werden vielleicht feststellen, dass ich nach dem Ausführen des Tests die Antwort "Es gibt nichts zu tun" vorschlage, weil es so funktioniert, wie es ist.

Ben Thul
quelle
Danke Ben. Ich fange an zu verstehen, dass mehr Variablen im Spiel sind, als ich zuerst dachte. Und ich akzeptiere, dass "versuchen und sehen" praktisch der vernünftigste Ansatz ist. Da es sich bei SQL Server im Wesentlichen um ein Programm handelt (ein sehr kompliziertes Programm), ist ein Teil von mir über diese mangelnde Vorhersehbarkeit frustriert.
Martin Hansen Lennox
1
@MartinHansenLennox und Ben: Ich stimme definitiv dem "try it" -Ansatz zu, anstatt nur auf Ratschläge oder persönliche Spekulationen zu hören. Ich würde jedoch empfehlen, in diesem Absatz genauer anzugeben, was es bedeutet, es wirklich auszuprobieren. Es ist mehr als nur das Laden und Ausführen von Abfragen. Das Testen muss das schrittweise Hinzufügen von Daten umfassen, um festzustellen, ob / wie sich die Dinge ändern, wenn sich Statistiken ändern und Indizes fragmentiert werden usw. Und versuchen Sie, Indizes zu sichern, wiederherzustellen, neu zu erstellen usw. Es ist zu beachten, dass partitionierte Indizes ab 2012 nicht mehr vorhanden sind Erhalten Sie beim Wiederherstellen eine vollständige Statusaktualisierung.
Solomon Rutzky
@MartinHansenLennox: Sie sind zu Recht frustriert über den Ansatz "Probieren Sie es aus und sehen Sie". SQL Server ist sehr vorhersehbar und es ist zumindest theoretisch möglich, das Problem zu analysieren, bevor Sie es versuchen. Das dafür erforderliche Hintergrundwissen macht dies jedoch häufig schwierig.
Thomas Kejser
7

Ich werde einen anderen Ansatz verfolgen und feststellen, dass die Partitionierung ( in SQL Server ) in erster Linie eine Datenverwaltungsfunktion ist, wobei die Abfrageleistung ein mögliches sekundäres Ergebnis ist, je nachdem, wie Sie sie verwalten . 1

Wie im verlinkten Artikel erwähnt, besteht der Hauptvorteil der Partitionierung darin, dass Sie Daten mithilfe der Partitionsumschaltung schnell verschieben können . Sie können beispielsweise "kühlere" Daten in einem langsameren Speicher archivieren und Ihre "heißen" Daten schnell speichern. In regelmäßigen Abständen können Sie Daten schnell archivieren, indem Sie sie auf Archivierungspartitionen rollen, ohne auf eine ETL warten zu müssen, um die Übertragung durchzuführen. Wie in einem der ersten Kommentare zu Ihrer Frage erwähnt, erfordert dies jedoch einige sorgfältige Überlegungen und Planungen, bevor Sie sie implementieren. Abhängig von der von Ihnen verwendeten SQL Server-Edition (Enterprise) können Sie die Datenkomprimierung auch zum Komprimieren einzelner Partitionen nutzen.

Soweit die Leistung betrifft, so können Sie die Sperreneskalation ändern AUTO(Standard TABLE) wie so :

ALTER TABLE dbo.T1 SET (LOCK_ESCALATION = AUTO);
GO

Darüber hinaus können Sie möglicherweise Partitionen entfernen, aber Ihre Abfragemuster müssen zu einem sehr spezifischen und wiederholbaren Muster in Ihrem System passen - der Partitionierungsschlüssel und der Clustering-Schlüssel sowie alle eindeutigen Schlüssel werden miteinander verbunden und sind sehr wichtig . Wenn dieses Gleichgewicht nicht anerkannt und darauf ausgelegt ist, kommt es zu Leistungsalpträumen.

Mit dem Aufkommen von SQL Server 2014 können Sie auch inkrementelle Statistiken nutzen. Dies ist sehr praktisch, wenn Sie Statistiken proaktiv in großen Tabellen überwachen und aktualisieren / erstellen.

Ab wann sollte eine Tabelle partitioniert werden? Dies hängt von Ihrer Abfragearbeitslast und dem Profil Ihrer Daten ab. Vor allem aber davon, welche Verwaltungsfunktionen für die Partitionierung Sie unbedingt nutzen müssen. Die Partitionierung dient nicht der Abfrageleistung, sondern hauptsächlich der Datenverwaltung und -verwaltung.

Swasheck
quelle
2
"Partitionierung dient nicht der Abfrageleistung, sondern hauptsächlich der Datenverwaltung und -verwaltung" - scheint offensichtlich, wenn Sie es sagen, aber ich hatte es noch nie ganz verstanden. Tolle Links übrigens, danke
Martin Hansen Lennox
Vielen Dank, dass Sie erwähnt haben, dass diese Funktion in erster Linie der Verwaltung und nicht der Leistung dient. Ich sehe das selten erwähnt und es ist ziemlich frustrierend.
Solomon Rutzky
1
@MartinHansenLennox: Partitionierung wird auch für die Leistung hervorragend eingesetzt. Zum Beispiel, wenn Sie Hash-Partitionierungstricks verwenden und Werte mit geringer Kardinalität verwenden.
Thomas Kejser
7

Bevor Sie entscheiden, wie groß die Partition sein soll, sollten Sie die Auswirkungen der Partitionierung auf den Abfrageplan berücksichtigen. Aus rein leistungsbezogener Sicht dienen Partitionen als grobkörniger Index. Dies kann zusätzliche Leistung bieten, ist jedoch auch eine Quelle für Leistungsregressionen, insbesondere wenn der Partitionsschlüssel nicht in allen Abfragen angezeigt wird. Von hier aus gehe ich davon aus, dass Sie diese Hausaufgaben bereits gemacht haben (wie es scheint).

Eine gute Faustregel für die gewünschte Partitionsgröße lautet: Etwa halb so groß wie der DRAM, den Sie auf der Box haben. Der Grund für diese Empfehlung ist:

  1. Sie können die Indizes auf der Partition neu erstellen, ohne sie zu verschütten tempdb. Dies ist VIEL schneller als bei Verwendung des Festplattenzugriffs (auch mit SSD).
  2. Während Sie diese Neuerstellung durchführen, können Sie immer noch eine ganze Partition (normalerweise die neueste) im DRAM halten, damit Ihre Abfrageleistung gut funktioniert.

Mit anderen Worten, Sie möchten genügend DRAM für zwei Partitionen haben, und die gewünschte Partitionsgröße hängt von dem Computer ab, auf dem Sie ausgeführt werden. Größere Maschinen können größere Partitionen bequem handhaben.

Beachten Sie, dass diese Anleitung auch eine Mindestgröße für Folgendes enthält tempdb: Mindestens die Größe Ihrer größten Partition (Sie können also den dort erstellten Index verschütten, wenn beim Neuerstellen eines Index nicht genügend DRAM vorhanden ist).

Sie können kleinere Partitionsgrößen als diese in Betracht ziehen. Wenn Sie dies jedoch tun, dient dies normalerweise der Leistungsoptimierung und nicht der Unterstützung der Verwaltbarkeit der Daten.

Es gibt eine Menge anderer Tricks, die Sie mit Partitionen spielen können. Zum Beispiel Komprimieren, Aggregieren oder Verwenden des Füllfaktors 100 für schreibgeschützte Partitionen. Das Grundprinzip lautet jedoch weiterhin: Versuchen Sie, jeden von Ihnen verwalteten Datenblock kleiner als DRAM zu halten.

PS: Schön zu sehen, dass Sie "es kommt darauf an" nicht als Antwort nehmen, fragen Sie immer nach einer Methode, um die Antwort zu erhalten.

Thomas Kejser
quelle
Vielen Dank an Thomas, gute Ratschläge, besonders die Erklärungen zur Partitionsgröße.
Martin Hansen Lennox
7

Die Tabellenpartitionierung wird wie einige andere Funktionen häufig (oder möglicherweise sogar am häufigsten?) Unangemessen verwendet. Alle Vorsichtsmaßnahmen, die ich geben würde, wurden in der Antwort von @ swasheck gut formuliert .

Eine zu berücksichtigende Alternative sind außerdem partitionierte Ansichten. Auf diese Weise können vollständig getrennte Tabellen beibehalten, aber über UNION ALL in einer Ansicht miteinander verknüpft werden. Für jede Tabelle ist eine CHECK CONSTRAINT erforderlich, um zu erzwingen, welcher Datenbereich jede Tabelle enthält. Der Optimierer kennt dieses Konstrukt und sollte nur über die Ansicht auf die zugrunde liegenden Tabellen zugreifen, die für eine Abfrage erforderlich sind (ich erinnere mich nicht an alle Anforderungen, damit diese Funktion wie beabsichtigt funktioniert. Lesen Sie daher bitte den Link CREATE VIEW unten) Ich habe es schon einmal eingerichtet und es war nicht schwierig, es wie erwartet zum Laufen zu bringen.

Es gibt definitiv einige Einschränkungen, und ein Hauptnachteil ist, dass es im Vergleich zur Tabellenpartitionierung weniger transparent ist. Ein Hauptvorteil besteht jedoch darin, dass es sich um separate Tabellen handelt und die Statistiken daher vollständig getrennt sind, während sie bei einer partitionierten Tabelle für die gesamte Tabelle gelten (auch wenn Sie ab SQL Server 2014 die Statistiken pro Partition aktualisieren können).

Wenn Sie Partitionen nicht ein- und ausschalten möchten, sollten Sie diese Option in Betracht ziehen. Insbesondere, wenn sich die älteren Daten nicht wesentlich ändern, da für die Tabellen mit den älteren Daten die Indizes / Statistiken nicht fast so oft aktualisiert werden müssen (oder möglicherweise jemals, wenn sich diese Daten nie ändern).

Ein weiterer Nachteil der Tabellenpartitionierung, der allzu oft nicht erwähnt / unbemerkt bleibt, ist, dass Sie ab SQL Server 2012 beim Neuerstellen partitionierter Indizes keine "kostenlosen" UPDATE-STATISTIKEN MIT FULLSCAN mehr erhalten. Sie erhalten diese Update-Statistiken immer noch mit einer Neuerstellung für nicht partitionierte Indizes, die die Indizes für die Tabellen in einer partitionierten Ansicht wären :).

Weitere Informationen zu partitionierten Ansichten finden Sie auf der MSDN-Seite für CREATE VIEW. Weitere Informationen finden Sie im Abschnitt "Partitionierte Ansichten" unter "Anmerkungen".

Solomon Rutzky
quelle
2
Toller Punkt zu den UPDATE STATISTICS. Indizierte Ansichten umgehen viele Partitionierungsprobleme, wenn Sie die Auswirkungen des Optimierers bewältigen können.
Thomas Kejser