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:
- Wenn wir eine sehr große Datenbank haben (150M + Zeilen in mehreren Tabellen)
- 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?
Antworten:
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
quelle
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 ;-)
quelle
Nein.
Es ist nicht praktisch, "alles" zu indizieren, aber Sie können "das meiste" davon indizieren.
Hier ist das Ding. Wenn eine Tabelle
N
Spalten enthält, beträgt die Anzahl der möglichen IndizesN!
. Angenommen, eine Tabelle hat 10 Spalten, dann haben Sie nicht nur10
mögliche Indizes, sondern10!
. 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.
quelle
Nein, es wird wahrscheinlich keine negativen Auswirkungen auf die
SELECT
Abfragen haben, aberINSERT
.WHERE
Bedingungsausdrücke verwenden noch keine Indizes, hauptsächlich die komplexeren.quelle