Ist es schlecht, wenn der Indexbereich größer als der Datenbereich ist?

22

Oft muss ich Abfragen für große Tabellen ausführen, die nicht den richtigen Index haben. Deshalb bitte ich den DBA, einen solchen Index zu erstellen. Das erste, was er tut, ist die Tabellenstatistik und die Größe des Indexbereichs.

Oft sagte er mir, ich solle eine alternative Lösung finden, weil "der Index bereits größer ist als die Tabelle". Er meint, der Index müsse kleiner sein als die Daten, weil er mir sagte: "Haben Sie den Index jemals in einem Buch gesehen? Er ist viel kleiner als das Buch selbst, und so sollte ein Tabellenindex sein."

Ich glaube nicht, dass seine Philosophie richtig ist, aber ich kann ihn nicht herausfordern, weil er ein leitender DBA ist und ich ein Entwickler bin. Ich denke, wenn eine Abfrage einen Index benötigt, sollte der Index nur erstellt werden, anstatt "Workarounds" zu finden, die nur unlesbare und nicht wartbare SPs erzeugen.

Ich wähle nur die erforderlichen Spalten aus. Das Problem besteht darin, dass ich nach Datum filtere, damit die Engine unbedingt einen Tabellenscan durchführt, um die Spalten abzugleichen. Die Abfrage wird einmal am Tag und nachts ausgeführt, um Statistiken zu erfassen. Die Ausführung dauert jedoch 15 Minuten (wir haben eine andere feste Regel: Kein Vorgang sollte länger als 3 Minuten dauern).

Der DBA hat mir die Indexstatistik gezeigt. Es gab ungefähr 10 Indizes auf dieser Tabelle, von denen nur 6 verwendet wurden (Statistiken zeigten null Treffer zu 4 von ihnen). Dies ist ein großes System mit über 20 teilnehmenden Entwicklern. Die Indizes wurden aus irgendeinem Grund erstellt und wahrscheinlich nicht mehr verwendet.

Wir müssen SQL Server 2008 unterstützen, da auf diesen Datenbanken die Tests ausgeführt werden. Aber die Kunden sind alle auf 2014 und 2016.

hjf
quelle

Antworten:

34

Stellen Sie sich das Indexdesign wie einen Schiebeschalter vor. Sie können diesen roten Dreieckschalter an eine beliebige Stelle entlang der gewünschten Linie bewegen:

Entscheidungen zum Indexdesign

Normalerweise messe ich es nicht in Bezug auf die Größe - ich denke es normalerweise in Bezug auf die Indexmenge, aber die Größe wäre auch in Ordnung.

Es hört sich so an, als ob Ihr DBA denkt, dass der Schalter zu weit rechts liegt - dass Sie zu viele Indizes hinzugefügt haben und das Löschen / Aktualisieren / Einfügen zu langsam ist.

Fragen Sie ihn nach den Leistungsproblemen, die Sie aufgrund der hohen Anzahl von Indizes haben, anstatt sich über die Position des Schalters zu streiten. Möglicherweise beschweren sich Ihre Benutzer über die Geschwindigkeit beim Löschen / Aktualisieren / Einfügen, oder es ist schwierig, die Datenbank aufgrund ihrer Größe zu sichern.

Mein Ausgangspunkt ist normalerweise 5 und 5: ungefähr 5 Indizes pro Tabelle mit ungefähr 5 oder weniger Feldern pro Index. Es ist nichts Magisches an dieser Zahl - es kommt einfach von der Tatsache, dass ich 5 Finger an jeder Hand habe, so dass es einfach ist, meine Hände hochzuhalten und die Regel zu erklären.

Möglicherweise benötigen Sie weniger als 5 Indizes, wenn Ihre Arbeitslast stark auf Lösch-, Aktualisierungs- und Einfügevorgänge ausgerichtet ist und Sie nicht über genügend Hardware-Leistung verfügen, um mithalten zu können.

Möglicherweise verfügen Sie über viele weitere Indizes, wenn Ihre Workload überwiegend schreibgeschützt ist oder wenn Sie stark in Hardware investieren (z. B. wenn Sie die gesamte Datenbank im Arbeitsspeicher zwischenspeichern und den gesamten Solid-State-Speicher darunter haben).

Brent Ozar
quelle
4

Auch der Wunsch, mehr als "The Ozar 5" -Indizes in einer Tabelle zu haben, deutet wahrscheinlich darauf hin, dass in der Tabelle viele verschiedene Arten von Abfragen mit hohem Leseaufwand vorhanden sind.

Was zeigt wahrscheinlich , dass Sie von einem gruppierten oder nicht gruppierten profitieren könnten columns Index auf dem Tisch.

Anstatt den optimalen Index für jeden von N verschiedenen Zugriffspfaden zu haben, können Sie mit einem Spaltenspeicher blitzschnell scannen und nicht benötigte Spalten und Zeilensegmente überspringen. So können Sie eine kleine Anzahl von BTree-Indizes für überkritische Transaktionen haben und für alles andere auf den Columnstore zurückgreifen.

Columnstore-Indizes sind für die Verwendung in OLTP-lastigen Workloads mit SQL Server 2016+ ausgelegt. Weitere Informationen finden Sie in der Dokumentation zur Echtzeit-Betriebsanalyse .

David Browne - Microsoft
quelle
3

Ich mag Brents Antwort und ich habe es positiv bewertet. Ich möchte jedoch eine andere Perspektive hinzufügen. Ich habe als Benutzer, Entwickler und Datenbankadministrator gearbeitet und bin der Meinung, dass Meinungen nicht relevant sind. Ich glaube, es liegt an dem Benutzer (oder Stakeholder), zu entscheiden, wie eine Abfrage ausgeführt wird und wie lange es dauert, bis Ergebnisse erzielt werden. Es ist dann Aufgabe des Entwicklers und des DBAs, zusammenzuarbeiten, um dies zu erreichen.

Wenn die DBA-Position in Ihrem Unternehmen für dieses Thema zuständig ist, kann sie Ihre Abfrage analysieren und Vorschläge für ein besseres Abfragedesign machen oder für die Leistung antworten.

Wenn die Abfrage- und / oder Datenstruktur nicht geändert werden kann, um das Ziel zu erreichen, sind meines Erachtens drei Optionen ausschlaggebend.

  1. Langsamer Datenabruf
  2. Langsame Datenaktualisierung
  3. Weitere Hardwareressourcen $$$$

Natürlich hat jede Situation viele Variablen, die von mehreren Geschäfts- und Technologiefaktoren abhängen, aber ich glaube, dass die drei Optionen für die meisten, wenn nicht für alle Fälle gelten.

Joe
quelle
0

Scheint zu streng, um Indizes> table zu verbieten. Wenn sich Ihre Tabelle selten ändert (oder sich nachts ändert, wenn nicht viel Konkurrenz um Ressourcen besteht) und sie auf viele verschiedene Arten häufig abgefragt wird, können viele große Indizes gerechtfertigt werden. DBAs sollten auch darauf achten, ihre Nase nicht dort zu stecken, wo sie nicht hingehört. Wenn er Ihnen / Ihrem System ein Limit für Gigabyte gibt, sollte es ihn nicht interessieren, wie dieser Raum genutzt wird. Wenn er überarbeitet ist, könnte dies der Grund sein.

Es gibt jedoch viele Dinge zu beachten:

  • Viele Indizes verlangsamen das Einfügen / Aktualisieren / Löschen. Wenn sich Ihr Tisch also stark ändert, achten Sie darauf, nicht zu viele davon zu machen.
  • Platz kann auch ein Problem sein. Nicht nur, weil Gigabyte Geld kosten (heutzutage nicht viel), sondern auch, weil das Backup langsamer sein wird (abhängig davon, wie das Backup durchgeführt wird).
  • Die meisten seriösen Datenbanken können überwacht werden, um Indizes zu finden, die selten oder nie verwendet werden. Ziehen Sie in Betracht, einige von ihnen fallen zu lassen.
  • Manchmal denken Sie, Sie benötigen einen Index, aber wenn Sie Ihre Abfrage genauer untersuchen, kann sie mit dem gleichen Ergebnis und ohne den Index unterschiedlich optimiert und umgeschrieben werden. Verwenden Sie EXPLAIN PLAN, um festzustellen, ob der Index verwendet wird oder nicht.
  • Manchmal können die letzten Spalten aus einem mehrspaltigen Index entfernt werden, ohne dass dies zu Leistungseinbußen führt. Und manchmal kann dies sogar Abfragen beschleunigen, da der Speicherplatz des Index kleiner ist und mehr des Index zu einem bestimmten Zeitpunkt im Speicher gehalten / zwischengespeichert wird.
  • Funktionsbasierte Indizes können normale Indizes ersetzen, um mehr Platz zu sparen. Beispiel: Anstatt nach dem vollständigen Nachnamen zu fragen, fragen Sie auch nach den ersten beiden Buchstaben ( where substr(surname, 1, 2) = substr(<userinput>, 1, 2) and surname=<userinput>) und create index i on customers(substr(surname,1,2)). Dies kann schnell genug sein und Ihr Index wird kleiner.
  • Datenbanken unterstützen verschiedene Arten von Indizes. Einige Typen benötigen weniger Platz als andere. Vielleicht können einige Ihrer Indizes in einen weniger platzraubenden Typ konvertiert werden? Stellen Sie zunächst sicher, dass Sie die verschiedenen Indextypen kennen und wissen, in welchen Situationen sie gut und schlecht sind.
  • Wenn nur ein seltener Stapeljob einen bestimmten Index benötigt, können Sie diesen Index nur für diesen Stapeljob erstellen und anschließend löschen.
Kjetil S.
quelle