Wenn eine Datenbank immer nur eine Einfügung hat, ist es dann schlecht, jede mögliche Spaltenkombination zu indizieren?


23

Ich arbeite an einem Berichtssystem, das umfangreiche Auswahlabfragen erfordert, jedoch auf einer Datenbank basiert, die nur einmal gefüllt wird. Das Datenbankverwaltungssystem ist Microsoft SQL Server 2017. Es gibt wahrscheinlich einen besseren Weg, ein System wie dieses zu entwerfen, aber gehen wir dies theoretisch an.

Theoretisch gesehen:

  1. Wenn wir eine sehr große Datenbank haben (150M + Zeilen in mehreren Tabellen)
  2. Und wir können davon ausgehen, dass die Datenbank nur einmal ausgefüllt wird.

Kann die Indizierung jeder möglichen Spaltenkombination die Leistung einer ausgewählten Abfrage beeinträchtigen?


4
Jede mögliche Kombination ist die meiste Zeit unpraktisch. Sinnvoller ist es, manuell, aber sehr großzügig zu indizieren. Das kann durchaus Sinn machen.
USR

12
Ich schlage vor, entweder Ihren Titel oder Ihren fett gedruckten Text neu zu formulieren, damit sie konsistent sind. Auf einen Blick war ich verwirrt von der höchststimmigen Antwort "Ja"
aaaaaa

150 Millionen Zeilen sind für eine einzelne Tabelle groß, für eine Datenbank jedoch nicht. In der Praxis verwenden Berichtssysteme nur einen kleinen Teil der möglichen Spaltenkombinationen. Es ist am besten, sich zunächst auf die Tastenkombinationen zu konzentrieren und diese dann nur bei Bedarf zu komplexieren.
Pojo-Guy

Antworten:


36

Ja, dies hat Einfluss auf die Kompilierungszeit des anfänglichen Plans, da das Optimierungsprogramm über viele zusätzliche Zugriffspfade auf die zu berücksichtigenden Daten verfügt.

Wenn Sie SQL Server 2017 verwenden, einmal laden und Berichte ausführen, können Sie stattdessen auch einen Clustered-Column-Store-Index verwenden.

Dies scheint die ideale Lösung für Ihr Bedürfnis zu sein, jede mögliche Spaltenkombination zu indizieren.

Columnstore-Indizes - Übersicht


Columnstore ist, wohin ich auch gehen würde, aber ich frage mich nur ... Funktioniert der Optimierer nicht genau im Gegenteil zu dem, was Sie beschrieben haben? Ich meine, anstatt verfügbare Indizes zu durchsuchen und sich zu fragen, welche von ihnen nützlich sein könnten, zaminiert es nicht die Abfrage und "überlegt" sich einen perfekten Index für diese Abfrage, dann prüft es, ob er existiert? (Wenn dies nicht der Fall ist, wird eine fehlende Indexnachricht generiert.) Wenn ich Recht habe (ich weiß es nicht, rate nur), sollte es auch bei Tausenden von Indizes nicht merklich länger dauern als mit nur mehreren von ihnen.
Limonka

26

Wenn Sie N Spalten in einer Tabelle haben, ist jede mögliche Spaltenkombination 2 ^ N-1 (Entfernen der leeren Menge). Für 10 Spalten, die 1023 Indizes bedeuten würden, erhalten wir für 20 Spalten satte 1048575 Indizes. Die meisten Indizes werden niemals verwendet, müssen jedoch vom Optimierer berücksichtigt werden. Es ist möglich, dass der Optimierer einen suboptimalen Index anstelle eines besseren wählt. Ich würde nicht alle Arten von Indizes generieren, anstatt herauszufinden, welche Indizes tatsächlich von Vorteil wären.

EDIT korrigierte Anzahl möglicher Indizes

Wie Jeff betont, ist es noch schlimmer als 2 ^ N (Potenz), da (3,2,1) sich deutlich von (1,2,3) unterscheidet. Für N Spalten können wir die erste Position in einem Index auswählen, die alle Spalten auf N Arten enthält. Für die zweite Position auf N-1-Wegen usw. haben wir also N! verschiedene Indizes voller Größe. Keiner dieser Indizes wird von einem anderen Index in dieser Gruppe subsummiert. Darüber hinaus können wir keinen weiteren kürzeren Index hinzufügen, damit dieser nicht von einem vollständigen Index abgedeckt wird. Die Anzahl der Indizes beträgt daher N !. Das Beispiel für 10 Spalten wird daher zu 10! = 3628800 Indizes und für 20 (Trommel) 2432902008176640000 Indizes. Dies ist eine lächerlich große Zahl. Wenn wir einen Punkt für jeden Index von einem Millimeter pro Teil setzen, dauert es 94 Tage, bis ein Lichtstrahl alle Punkte durchläuft. Alles in allem nicht ;-)


6
Schlimmer noch: Die Reihenfolge der Spalten im Index kann wichtig sein. Sie erhalten also maximal N! Indizes.
Jeff

2
Sie benötigen jedoch keine Indizes, die Präfixe anderer Indizes sind.
Barmar

3
Es ist noch schlimmer. Für jeden Index gibt es ASC- und DESC-Kombinationen.
ypercubeᵀᴹ

2
Und noch viel schlimmer, es gibt INCLUDE-Indizes.
ypercubeᵀᴹ

2
Und eine Vielzahl von Teilindizes.
ypercubeᵀᴹ

7

Nein.

Es ist nicht praktisch, "alles" zu indizieren, aber Sie können "das meiste" davon indizieren.

Hier ist das Ding. Wenn eine Tabelle NSpalten enthält, beträgt die Anzahl der möglichen Indizes N!. Angenommen, eine Tabelle hat 10 Spalten, dann haben Sie nicht nur 10mögliche Indizes, sondern 10!. Das sind 3.628.800 auf einem Tisch. Das ist viel Speicherplatz, Festplatten-E / A, Cache und Suchzeiten.

Warum? Ein paar Gründe:

  • Lightwwight-Indizes werden normalerweise zwischengespeichert, wodurch sie blitzschnell sind. Wenn Sie 3 Millionen von ihnen haben, werden sie NICHT zwischengespeichert.

  • Das SQL-Optimierungsprogramm kann eine Menge Zeit in Anspruch nehmen, um zu entscheiden, welches besser zu verwenden ist, insbesondere wenn Verknüpfungen verwendet werden.

  • Das SQL-Optimierungsprogramm gibt möglicherweise die Verwendung des umfassenden Algorithmus auf und versucht stattdessen einen heuristischen Algorithmus. Dies kann "weniger als optimal" sein. PostgreSQL bietet beispielsweise verschiedene Optionen für "weniger als 8 Tabellenabfragen" und "mehr als 8 Tabellenabfragen".

  • Indizes sollen leichter sein als der Haufen. Wenn Sie alles indizieren, wird der Index so schwer wie der Haufen ... etwas, das den Zweck des Indexes zunichte macht.


Ist die Zahl nicht 2 ^ 10? Jede Spalte ist in einem bestimmten Index enthalten oder davon ausgeschlossen. Ist die Bestellung wichtig?
RemcoGerlich

2
@RemcoGerlich ja, die Reihenfolge ist wichtig.
ypercubeᵀᴹ

2

Nein, es wird wahrscheinlich keine negativen Auswirkungen auf die SELECTAbfragen haben, aber

  • Dies führt zu einer hohen Datenträgernutzung.
  • Das wird die Kosten enorm erhöhen INSERT.
  • Die meisten Ihrer Indizes werden niemals verwendet.
  • Viele WHEREBedingungsausdrücke verwenden noch keine Indizes, hauptsächlich die komplexeren.
  • Die Anzahl der erforderlichen Indizes steigt exponentiell mit der Anzahl der Spalten. Dh wenn Sie zum Beispiel 8 Spalten haben, benötigen Sie 256 Indizes für alle möglichen Kombinationen.

Dies kann zu Problemen bei der Kompilierung führen.
Erik Darling

@sp_BlitzErik Denkst du zum ORM in der App?
Peter sagt, Monica

Nein, siehe meine Antwort.
Erik Darling

@sp_BlitzErik Wow, schön zu sehen!
Peter sagt, Monica
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.