Wann ist es besser, STATISTIKEN zu erstellen, anstatt einen Index zu erstellen?


38

Ich habe viel Informationen zu finden auf was STATISTICS sind: wie sie erhalten bleiben, wie sie manuell erstellt werden oder automatisch aus Abfragen oder Indizes, und so weiter. Ich konnte jedoch keine Anleitung oder Informationen zu "Best Practices" bezüglich des Zeitpunkts findenum sie zu erstellen: Welche Situationen profitieren mehr von einem manuell erstellten STATISTICS-Objekt als von einem Index? Ich habe manuell erstellte gefilterte Statistiken gesehen, die bei Abfragen von partitionierten Tabellen helfen (weil die für die Indizes erstellten Statistiken die gesamte Tabelle abdecken und nicht pro Partition sind - Brillaint!), Aber es muss sicherlich andere Szenarien geben, die von einem Statistikobjekt währenddessen profitieren würden Sie benötigen weder die Details eines Index noch die Kosten für die Aufrechterhaltung des Index oder die Erhöhung der Wahrscheinlichkeit von Blockierungen / Dead-Locks.

@ JonathanFite erwähnte in einem Kommentar eine Unterscheidung zwischen Indizes und Statistiken:

Indizes helfen SQL dabei, die Daten schneller zu finden, indem sie Lookups erstellen, die anders sortiert sind als die Tabelle selbst. Mithilfe von Statistiken kann SQL ermitteln, wie viel Arbeitsspeicher / Aufwand erforderlich ist, um die Abfrage zu erfüllen.

Das sind großartige Informationen, vor allem, weil es mir hilft, meine Frage zu klären:

Inwieweit hilft die Kenntnis dieser (oder anderer technischer Informationen darüber, was und wie sie mit dem Verhalten und der Art von zusammenhängen STATISTICS) zu bestimmen, wann eine Auswahl getroffen CREATE STATISTICSwerden muss CREATE INDEX, insbesondere wenn ein Index erstellt wird, um das zugehörige STATISTICSObjekt zu erstellen ? Für welches Szenario ist es besser, nur die STATISTICS-Informationen und nicht den Index zu haben?

Es wäre sehr hilfreich, wenn Sie ein funktionierendes Beispiel für ein Szenario hätten, in dem das STATISTICSObjekt besser passt als ein INDEX.


Da ich ein visueller Lernender / Denker bin, dachte ich, es könnte hilfreich sein, die Unterschiede zwischen STATISTICSund INDEXnebeneinander zu sehen, um herauszufinden, wann STATISTICSdie bessere Wahl ist.

Thingy           PROs                             CONs
-------          ----------                       -------------------
INDEX            * Can help sorts.                * Takes up space.
                 * Contains data (can             * Needs to be maintained (extra I/O).
                   "cover" a query).              * More chances for blocking / dead-locks.

STATISTICS       * Takes up very little space.    * Cannot help sorts.
                 * Lighter maintenance / won't    * Cannot "cover" queries.
                   slow down DML operations.
                 * Does not increase chances
                   of blocking / dead-locks.

Das Folgende sind einige Ressourcen, die ich gefunden habe, als ich danach gesucht habe, eine, die sogar dieselbe Frage stellt, aber nicht beantwortet wurde:

SQL Server Index vs Statistik

Fragen zu SQL Server-Statistiken, die wir nicht beantworten konnten

Statistiken. Sind mehrspaltige Histogramme möglich?

** Um es klar auszudrücken, ich habe keine Antwort darauf und freue mich darauf, von hoffentlich ein paar Leuten Feedback zu bekommen, um etwas zu liefern, das hier in den Interwebs seltsamerweise zu fehlen scheint.


1
Indizes helfen SQL dabei, die Daten schneller zu finden, indem sie Lookups erstellen, die anders sortiert sind als die Tabelle selbst. Mithilfe von Statistiken kann SQL ermitteln, wie viel Arbeitsspeicher / Aufwand erforderlich ist, um die Abfrage zu erfüllen.
Jonathan Fite

@ JonathanFite Vielen Dank für diesen Kommentar. Ich habe es in meine Frage aufgenommen :).
Solomon Rutzky

Nach dem Kommentar von @ JonathanFite scheinen Statistiken am besten geeignet zu sein, um die Leistung von Ad-hoc-Systemen, -Tabellen und -Abfragemustern zu steigern, während Indizes besser für vorhersagbare Abfragemuster geeignet sind. Ich meine das eher als Frage als als Aussage.
Dave

Antworten:


19

Ihre Frage dreht sich um Folgendes: Wann ist es eine gute Sache, nur Statistiken zu erstellen, anstatt einen Index zu erstellen (der Statistiken erstellt)?

Aus meiner SQL Server - Interna Notes (SQLSkills Klassen- IE1 und IE2) und SQL Server - Interna buchen , unten ist mein begrenzt Verständnis:

SQL Server-Statistiken sind nichts anderes als Systemobjekte, die wichtige Informationen zu den Indexschlüsselwerten und regulären Spaltenwerten enthalten.

SQL Server verwendet ein kostenbasiertes Modell, um so schnell wie möglich einen Ausführungsplan auszuwählen, der "gut genug" ist. Die Kardanilitätsschätzung (Schätzung der Anzahl der in jedem Schritt der Abfrageausführung zu verarbeitenden Zeilen) ist der wichtigste Faktor bei der Abfrageoptimierung, der sich auf die Join-Strategie, den Speicherbedarf, die Auswahl der Worker-Threads sowie die Auswahl der Indizes beim Datenzugriff auswirkt .

SQL Server verwendet keine nicht gruppierten Indizes, wenn geschätzt wird, dass ein großes Nein. Es ist eine Anzahl von KEY- oder RID-Loopup-Operationen erforderlich, sodass Statistiken zu Indizes (und zu Spalten) verwaltet werden, die bei solchen Schätzungen hilfreich sind.

Es gibt zwei wichtige Dinge über Statistiken:

  1. Das Histogramm speichert Informationen zur Datenverteilung NUR für die am weitesten links stehende Statistikspalte (Index). Es werden auch Informationen zur Mehrspaltendichte der Schlüsselwerte gespeichert. Im Wesentlichen speichert das Histogramm die Datenverteilung nur für die Statistikspalte ganz links.

  2. SQL Server behält unabhängig von der Tabellengröße höchstens 200 Schritte im Histogramm bei. Die Intervalle, die von den einzelnen Histogrammschritten abgedeckt werden, erhöhen sich mit der Vergrößerung der Tabelle, was bei großen Tabellen zu "weniger genauen" Statistiken führt.

    Beachten Sie, dass die Indexselektivität eine Metrik ist, die umgekehrt proportional zur Dichte ist. Je mehr eindeutige Werte eine Spalte hat, desto höher ist ihre Selektivität.

Wenn bestimmte Abfragen nicht sehr häufig ausgeführt werden, können Sie festlegen, dass Statistiken auf Spaltenebene statt eines Index erstellt werden. Mithilfe von Statistiken auf Spaltenebene kann das Abfrageoptimierungsprogramm bessere Ausführungspläne finden, obwohl diese Ausführungspläne aufgrund der beteiligten Indexprüfungen nicht optimal sind. Gleichzeitig verursachen Statistiken bei Datenänderungsvorgängen keinen zusätzlichen Aufwand und tragen zur Vermeidung der Indexpflege bei. Dieser Ansatz funktioniert nur bei selten ausgeführten Abfragen.

Verweisen :

Hinweis: Jemand wie Paul White oder Aaron Bertrand kann sich melden, um Ihrer guten Frage mehr Farbe zu verleihen .


"SQL Server verwendet keine nicht gruppierten Indizes, wenn geschätzt wird, dass eine große Anzahl von KEY- oder RID-Loopup-Vorgängen erforderlich ist." Kann die QO das auf einem Index basierende Statistikobjekt also unabhängig vom Index verwenden? Das heißt, wenn der Index nicht optimal ist, sich aber die führende Spalte in der Abfrage befindet, sind die Statistiken immer noch relevant. Würden sie also benutzt werden? Oder impliziert diese Information, dass es Fälle geben könnte, in denen ein Index wahrscheinlich nicht verwendet wird, aber da die Statistiken immer noch einen Wert haben, gibt es keinen wirklichen Grund, den Index zu erstellen, nur die Statistiken?
Solomon Rutzky

8

Ich würde sagen, Sie benötigen einen Index, wenn Sie die Datenmenge begrenzen / schnell auf die richtigen Daten basierend auf den Feldern zugreifen möchten.

Sie benötigen Statistiken, wenn der Optimierer die Art der Daten verstehen soll, um die Vorgänge bestmöglich ausführen zu können.

Wie ich herausgefunden habe, sind gefilterte Statistiken hilfreich, wenn Ihre Daten Abweichungen aufweisen, die sich stark auf den Plan auswirken, z. B. bei einem Stapelüberlauf. Nur wenige Benutzer haben eine große Anzahl von Posts. Daher ist es nicht wirklich die beste Schätzung, nur durchschnittliche Posts pro Benutzer zu verwenden. Sie könnten also eine gefilterte Statistik für userId erstellen, die auf dem Benutzernamen basiert, und dann sollte SQL Server wissen, dass, wenn dieser Benutzername in der Abfrage enthalten ist, dies die Benutzer-ID ist, die er erhält, und in der Lage sein sollte, das herauszufinden Das indizierte Feld in der Tabelle posts enthält eine große Anzahl von Zeilen mit dieser ID, da dort ein Histogramm vorhanden ist. Mit Durchschnittswerten ist das nicht möglich.


1
Hallo, und danke für die Antwort. Wann muss / möchte ich also, dass der Optimierer die Art der Daten besser versteht und diese Daten dennoch nicht einschränkt oder schneller darauf zugreifen möchte, oder muss er die Abfrage "abdecken"? Gleiches gilt für Ihr Beispiel mit gefiltertem Index. Ich verstehe, was Sie sagen, um Kantenfälle aus Durchschnittswerten herauszulösen, aber warum wäre die gefilterte Statistik besser als ein gefilterter Index für dieselben Felder? Dies ist die Unterscheidung, zu der ich zu gelangen versuche.
Solomon Rutzky

Wie im Beispiel können Sie keinen gefilterten Index für den Benutzernamen der Tabelle posts erstellen, da er dort nicht vorhanden ist. Sie könnten es basierend auf der Benutzer-ID erstellen, aber das steht nicht in der where-Klausel.
James Z

Aber wäre nicht UserIDin der JOIN-Bedingung, auch wenn nicht in der WHERE? Und wäre das nicht gut genug, um einen gefilterten Index aufzunehmen?
Solomon Rutzky

@srutzky Wahrscheinlich in den aktuellsten Versionen, aber im Allgemeinen würde ich mich nicht darauf verlassen ... In den meisten Fällen müssen die Prädikate genau übereinstimmen. Ich habe vergessen, ob sie dies behoben haben, aber an einer Stelle wurde kein gefilterter Index WHERE BitColumn = 0für eine einfache Abfrage ausgewählt WHERE BitColumn <> 1. (Und um klar zu sein, die Bitspalte war nicht nullwertfähig.) Ich glaube, es gab ähnliche Fälle wie IntColumn > 10Nichtübereinstimmung IntColumn >= 11.
Aaron Bertrand

Gefilterte Indizes können nicht verwendet werden, wenn die Möglichkeit besteht, dass der gefilterte Index bei der nächsten Verwendung der Pläne nicht mehr geeignet ist. Ich kann mir keine Joins vorstellen, die einen gefilterten Index verwenden könnten. Sogar Variablen können nicht verwendet werden, da der Wert beim nächsten Mal möglicherweise nicht geeignet ist.
James Z

4

Von 70-461 Schulungsbuch von Itzik Ben-Gan

Es gibt nur wenige mögliche Gründe, um Statistiken manuell zu erstellen. Ein Beispiel ist, wenn ein Abfrageprädikat mehrere Spalten mit spaltenübergreifenden Beziehungen enthält. Statistiken zu mehreren Spalten können zur Verbesserung des Abfrageplans beitragen. Statistiken für mehrere Spalten enthalten spaltenübergreifende Dichten, die in Einzelspaltenstatistiken nicht verfügbar sind. Wenn sich die Spalten jedoch bereits im selben Index befinden, ist das mehrspaltige Statistikobjekt bereits vorhanden, sodass Sie kein zusätzliches manuell erstellen sollten.


Danke, dass du das gepostet hast. Dies beantwortet einen Teil meiner Frage, lässt jedoch die Frage offen: Wenn ich die mehrspaltige Statistik benötige, warum sollte ich statt des Index nur die STATISTIKEN erstellen, die die STATISTIKEN und zusätzliche Informationen enthalten, die die Abfrage weiter unterstützen könnten ( ies)?
Solomon Rutzky

1
Ich denke, Kins Erklärung würde weiter erklären, wonach Sie suchen. Vielleicht ein Haufen, der häufig eingefügt, aber selten abgefragt wird?
Kentaro
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.