Wie viele Datenbankindizes sind zu viele?

109

Ich arbeite an einem Projekt mit einer ziemlich großen Oracle-Datenbank (obwohl meine Frage auch für andere Datenbanken gilt). Wir haben eine Weboberfläche, mit der Benutzer nach nahezu jeder möglichen Kombination von Feldern suchen können.

Um diese Suche zu beschleunigen, fügen wir den Feldern und Feldkombinationen, nach denen Benutzer unserer Meinung nach häufig suchen, Indizes hinzu. Da wir jedoch nicht genau wissen, wie unsere Kunden diese Software verwenden werden, ist es schwierig zu sagen, welche Indizes erstellt werden sollen.

Raum ist kein Problem; Wir haben ein 4-Terabyte-RAID-Laufwerk, von dem wir nur einen kleinen Bruchteil verwenden. Ich bin jedoch besorgt über die möglichen Leistungseinbußen bei zu vielen Indizes. Da diese Indizes jedes Mal aktualisiert werden müssen, wenn eine Zeile hinzugefügt, gelöscht oder geändert wird, halte ich es für eine schlechte Idee, Dutzende von Indizes in einer einzelnen Tabelle zu haben.

Wie viele Indizes werden als zu viele angesehen? 10? 25? 50? Oder sollte ich nur die wirklich, wirklich häufigen und offensichtlichen Fälle behandeln und alles andere ignorieren?

Eli Courtwright
quelle

Antworten:

87

Dies hängt von den Operationen ab, die in der Tabelle ausgeführt werden.

Wenn es viele SELECTs und sehr wenige Änderungen gibt, indizieren Sie alles, was Sie möchten. Dies beschleunigt (möglicherweise) die SELECT-Anweisungen.

Wenn die Tabelle stark von UPDATEs, INSERTs + DELETEs ... betroffen ist, sind diese mit vielen Indizes sehr langsam, da sie alle bei jeder dieser Operationen geändert werden müssen

Trotzdem können Sie einer Tabelle eindeutig viele sinnlose Indizes hinzufügen, die nichts bewirken. Das Hinzufügen von B-Tree-Indizes zu einer Spalte mit zwei unterschiedlichen Werten ist sinnlos, da nichts zum Nachschlagen der Daten hinzugefügt wird. Je eindeutiger die Werte in einer Spalte sind, desto mehr profitiert ein Index.

Cagcowboy
quelle
1
Zur Verdeutlichung ist der Index für 2 Werte in bestimmten Fällen möglicherweise nicht sinnlos, wenn ein Wert selten vorkommt und Sie ihn nachschlagen möchten. Es geht also nicht darum, wie eindeutig die Werte sind, sondern darum, wie selektiv der Index ist.
Charlie_pl
44

Normalerweise gehe ich so vor.

  1. Erstellen Sie ein Protokoll der tatsächlichen Abfragen, die an einem typischen Tag für die Daten ausgeführt werden.
  2. Fügen Sie Indizes hinzu, damit die wichtigsten Abfragen die Indizes in ihrem Ausführungsplan treffen.
  3. Vermeiden Sie die Indizierung von Feldern mit vielen Aktualisierungen oder Einfügungen
  4. Holen Sie sich nach einigen Indizes ein neues Protokoll und wiederholen Sie den Vorgang.

Wie bei jeder Optimierung höre ich auf, wenn die angeforderte Leistung erreicht ist (dies impliziert offensichtlich, dass Punkt 0 bestimmte Leistungsanforderungen erhalten würde).

Sklivvz
quelle
26

Alle anderen haben Ihnen gute Ratschläge gegeben. Ich habe einen zusätzlichen Vorschlag für Sie, wenn Sie vorwärts gehen. Irgendwann müssen Sie eine Entscheidung über Ihre beste Indexierungsstrategie treffen. Am Ende kann die beste geplante Indexierungsstrategie jedoch dazu führen, dass Indizes erstellt werden, die nicht verwendet werden. Eine Strategie, mit der Sie nicht verwendete Indizes finden können, ist die Überwachung der Indexnutzung. Sie tun dies wie folgt: -

alter index my_index_name monitoring usage;

Sie können dann überwachen, ob der Index von diesem Punkt an verwendet wird oder nicht, indem Sie v $ object_usage abfragen. Informationen hierzu finden Sie im Oracle® Database Administrator's Guide .

Denken Sie daran, dass Sie den Index für die erneute Überwachung einrichten müssen, wenn Sie eine Warehousing-Strategie haben, bei der Indizes vor dem Aktualisieren einer Tabelle gelöscht und anschließend neu erstellt werden. Dadurch geht der Überwachungsverlauf für diesen Index verloren.

Mike McAllister
quelle
14

Im Data Warehousing ist es sehr häufig, dass eine hohe Anzahl von Indizes vorhanden ist. Ich habe mit Faktentabellen mit zweihundert Spalten gearbeitet und 190 davon indiziert.

Obwohl dies mit einem Overhead verbunden ist, muss im Zusammenhang damit verstanden werden, dass wir in einem Data Warehouse eine Zeile im Allgemeinen nur einmal einfügen, sie jedoch nie aktualisieren. Sie kann dann jedoch an Tausenden von SELECT-Abfragen teilnehmen, die von der Indizierung einer beliebigen Zeile profitieren könnten die Spalten.

Für maximale Flexibilität verwendet ein Data Warehouse im Allgemeinen einspaltige Bitmap-Indizes, außer in Spalten mit hoher Kardinalität, in denen (komprimierte) btree-Indizes verwendet werden können.

Der Aufwand für die Indexpflege ist hauptsächlich mit den Kosten für das Schreiben in sehr viele Blöcke und die Blockaufteilung verbunden, wenn neue Zeilen mit Werten hinzugefügt werden, die "in der Mitte" der vorhandenen Wertebereiche für diese Spalte liegen. Dies kann durch Partitionierung und Ausrichtung der neuen Datenlasten auf das Partitionierungsschema sowie durch Verwendung direkter Pfadeinfügungen verringert werden.

Um Ihre Frage direkter zu beantworten, denke ich, dass es wahrscheinlich in Ordnung ist, zunächst das Offensichtliche zu indizieren, aber haben Sie keine Angst davor, weitere Indizes hinzuzufügen, wenn die Abfragen für die Tabelle davon profitieren würden.

David Aldridge
quelle
So viele auf eine Tatsache? Ich hätte gedacht, dass Sie gerade Dimension sagen würden. Das ist ein ziemlich bizarrer Fall. Aber du rockst als DBA, also werde ich sagen, ich vermisse offensichtlich etwas.
Stephanie Seite
@Stephanie, wir haben fast das gleiche Szenario. David hat erwähnt, dass dies Bitmap-Indizes sind. Wir verwenden auch BITMAP JOIN-Indizes. Ja, auf Fakten. Oracle kann sehr effiziente UND-Operationen an Bitmap-Indizes ausführen. Beispielsweise könnten Sie eine WHERE-Klausel mit 5 Attributen mit niedriger Kardinalität haben, von denen jedes einen Bitmap-Index hat. Wenn Sie sich den Ausführungsplan ansehen, enthält er eine Bitmap UND-Operationen (im Grunde eine effiziente Bitmap und Operation). Im Ausführungsplan wird dann die Bitmap-Konvertierung in Rowids angezeigt. Es ist sehr schnell.
Tagar
12

Fügen Sie in einer Umschreibung von Einstein über Einfachheit so viele Indizes hinzu, wie Sie benötigen, und nicht mehr.

Im Ernst, jeder Index, den Sie hinzufügen, muss gewartet werden, wenn Daten zur Tabelle hinzugefügt werden. Bei Tabellen, die hauptsächlich schreibgeschützt sind, sind viele Indizes eine gute Sache. Bei hochdynamischen Tabellen ist weniger besser.

Mein Rat ist, die häufigsten und offensichtlichen Fälle abzudecken und dann, wenn Sie auf Probleme stoßen, bei denen Sie mehr Geschwindigkeit beim Abrufen von Daten aus bestimmten Tabellen benötigen, zu diesem Zeitpunkt Indizes auszuwerten und hinzuzufügen.

Es ist auch eine gute Idee, Ihre Indexierungsschemata alle paar Monate neu zu bewerten, um festzustellen, ob es etwas Neues gibt, das indiziert werden muss, oder von Ihnen erstellte Indizes, die für nichts verwendet werden und entfernt werden sollten .

Josef
quelle
1
Ich stimme der Neubewertung zu. Gute Verwaltung ist niemals eine Aufgabe, bei der man es festlegt und vergisst. Softwareänderungen. Anforderungen ändern sich. Nutzungsänderungen. Eine neue, scheinbar triviale Funktionalität, die eines Tages eingeführt wird, kann schnell zu Ihrem größten Engpass werden, und der Grundstein für den Brot-und-Butter-Code von gestern kann inaktiv werden und unnötiges Fett enthalten, das nur um den Verbrauch von Ressourcen herum hängt. Ich stimme auch einem iterativen Ansatz zu. Wenn Sie zu viel auf einmal tun, wissen Sie nicht, was funktioniert hat.
Durette
6

Zusätzlich zu den Punkten, die alle anderen angesprochen haben, entstehen dem kostenbasierten Optimierer Kosten beim Erstellen eines Plans für eine SQL-Anweisung, wenn mehr Indizes vorhanden sind, da mehr Kombinationen zu berücksichtigen sind. Sie können dies reduzieren, indem Sie Bindungsvariablen korrekt verwenden, sodass SQL-Anweisungen im SQL-Cache verbleiben. Oracle kann dann eine weiche Analyse durchführen und den zuletzt gefundenen Plan wiederverwenden.

Wie immer ist nichts einfach. Wenn es sich um verzerrte Spalten und Histogramme handelt, kann dies eine schlechte Idee sein.

In unseren Webanwendungen beschränken wir die zulässigen Suchkombinationen. Andernfalls müssten Sie buchstäblich jede Kombination auf Leistung testen, um sicherzustellen, dass Sie kein lauerndes Problem haben, das eines Tages jemand finden wird. Wir haben auch Ressourcenbeschränkungen implementiert, um dies zu verhindern und Probleme an anderer Stelle in der Anwendung zu verursachen, falls etwas schief gehen sollte.

WW.
quelle
Ich habe abgestimmt, aber ... ich würde sagen, dass die zusätzliche Analysezeit zwar interessant und akademisch ist, aber niemals meine Wahl für die richtige Anzahl von Indizes beeinflusst. zustimmen?
Stephanie Seite
@StephaniePage Ich habe kein Experiment durchgeführt, um etwas zu beweisen. Ich habe jedoch ein Projekt gesehen, das naiv einen einspaltigen Index für jede Spalte erstellt hat. Wenn einige Tabellen 80 Spalten haben, könnte dies Auswirkungen haben. Oracle scheint die Kosten für den Zugriff jedes Index zu berücksichtigen. Aber ja, ich stimme zu, es gibt wichtigere Dinge zu beachten als dies.
WW.
Mmm ... Ich glaube, es gibt eine maximale Zeit, die Oracle für eine harte Analyse benötigt ... Betrachten Sie eine SQL mit mehr als ein paar Tabellen, z. B. 7 oder 8, allein die Auswahl der Verknüpfungsreihenfolge könnte Hunderte von möglichen generieren Zugangspfade.
Stephanie Seite
6

Ich habe einige einfache Tests an meinem realen Projekt und meiner realen MySQL-Datenbank durchgeführt. Ich habe bereits in diesem Thema geantwortet: Was kostet die Indizierung mehrerer Datenbankspalten?

Aber ich denke, es wird besser sein, wenn ich es hier zitiere:

Ich habe einige einfache Tests mit meinem realen Projekt und meiner realen MySQL-Datenbank durchgeführt.

Meine Ergebnisse sind: Hinzufügen eines durchschnittlichen Index (1-3 Spalten in einem Index) zu einer Tabelle - macht Einfügungen um 2,1% langsamer. Wenn Sie also 20 Indizes hinzufügen, sind Ihre Einfügungen um 40-50% langsamer. Ihre Auswahl ist jedoch 10-100-mal schneller.

Ist es also in Ordnung, viele Indizes hinzuzufügen? - Es kommt darauf an :) Ich habe dir meine Ergebnisse gegeben - Du entscheidest!

Nachtcodierer
quelle
Dies sollte nicht als Prophezeiung ohne alle Details verstanden werden. Insbesondere, weil Sie den Leistungsgewinn / -verlust nicht von einer Aktion zur nächsten multiplizieren können. Die Basis bleibt dieselbe: Fügen Sie weitere Indizes hinzu, und Ihre Einfügungen werden aufgrund der Indexwiederherstellung möglicherweise langsamer.
Sowjetische Frontier
3

Wie viele Indizes Sie letztendlich benötigen, hängt vom Verhalten Ihrer Anwendungen ab, die auf Ihrem Datenbankserver ausgeführt werden.

Im Allgemeinen werden Ihre Indizes umso schmerzhafter, je mehr Sie einfügen. Bei jeder Einfügung müssen alle Indizes, die diese Tabelle enthalten, aktualisiert werden.

Wenn Ihre Anwendung eine anständige Lesemenge aufweist, oder noch mehr, wenn fast ausschließlich gelesen wird, sind Indizes der richtige Weg, da sich die Leistung bei sehr geringen Kosten erheblich verbessern wird.

Orion Adrian
quelle
3

Meiner Meinung nach gibt es keine statische Antwort. Diese Art von Dingen fällt unter "Leistungsoptimierung".

Es kann sein, dass alles, was Ihre App tut, von einem Primärschlüssel nachgeschlagen wird, oder es könnte das Gegenteil sein, dass Abfragen über uneingeschränkte Feldkombinationen durchgeführt werden und jedes einzelne zu einem bestimmten Zeitpunkt verwendet werden kann.

Über die reine Indizierung hinaus wird Ihre Datenbank neu programmiert, um berechnete Suchfelder, Aufteilungstabellen usw. einzuschließen. Dies hängt wirklich von Ihren Ladeformen und Abfrageparametern ab, wie viel / welche Daten von einer Abfrage "wirklich" abgerufen werden müssen.

Wenn Ihre gesamte Datenbank mit Fassaden mit gespeicherten Prozeduren konfrontiert ist, wird das Drehen etwas einfacher, da Sie sich nicht um jede Ad-hoc-Abfrage kümmern müssen. Oder Sie haben ein tiefes Verständnis für die Art von Abfragen, die Ihre Datenbank treffen, und können die Optimierung auf diese beschränken.

Für SQL Server fand ich den Database Engine Tuning Advisor nützlich - Sie richten 'typische' Workloads ein und er kann Empfehlungen zum Hinzufügen / Entfernen von Indizes und Statistiken geben. Ich bin sicher, dass andere DBs ähnliche Tools haben, entweder "offiziell" oder von Drittanbietern.

Scotta
quelle
3

Dies ist wirklich eher eine theoretische als eine praktische Frage. Die Auswirkungen von Indizes auf Ihre Leistung hängen von Ihrer Hardware, der Oracle-Version, den Indextypen usw. ab. Gestern habe ich gehört, dass Oracle einen dedizierten Speicher von HP angekündigt hat, der mit 11g-Datenbanken zehnmal schneller arbeiten soll. Für Ihren Fall gibt es mehrere Lösungen: 1. Haben Sie eine große Anzahl von Indizes (> 20) und erstellen Sie diese täglich (jede Nacht) neu. Dies ist besonders nützlich, wenn die Tabelle täglich Tausende von Aktualisierungen / Löschungen erhält. 2. Partitionieren Sie Ihre Tabelle (falls dies für Ihr Datenmodell gilt). 3. Verwenden Sie eine separate Tabelle für neue / aktualisierte Daten und führen Sie einen nächtlichen Prozess aus, bei dem die Daten miteinander kombiniert werden. Dies würde eine Änderung Ihrer Anwendungslogik erfordern. 4. Wechseln Sie zu IOT (Index Organized Table), wenn Ihre Daten dies unterstützen.

Natürlich könnte es für einen solchen Fall viel mehr Lösungen geben. Mein erster Vorschlag an Sie wäre, die Datenbank in eine Entwicklungsumgebung zu klonen und einige Stresstests dagegen durchzuführen.

Moshe
quelle
Ich verstehe nicht, wie die Neuerstellung der Indizes helfen würde oder wie ein IOT helfen würde.
David Aldridge
IOT - Wenn es möglich ist, die Anwendung so zu gestalten, dass ein neuer benutzerdefinierter Datentyp verwendet wird, spart IOT den Aufwand für die Indizierung der Tabelle. Dies ist hier möglicherweise nicht der Fall. es kommt wirklich darauf an. Neuerstellung des Index - falls es viele Indizes gibt und neue Daten nicht indiziert werden.
Moshe
Ein IOT ist immer noch eine Indexstruktur mit mehr Overhead bei Blockaufteilungen als ein regulärer Index. "Neuerstellung des Index - falls es viele Indizes gibt und neue Daten nicht indiziert werden" ... von welchem ​​RDBMS sprechen Sie, das Indizes für neue Einträge nicht automatisch verwaltet?
David Aldridge
David - du hast natürlich recht. Ich habe das mit der Fähigkeit von SQL Server gemischt, die Volltextsuche nur nach Bedarf zu indizieren. Ich wünschte, Oracle hätte es, da es in diesem Fall nützlich sein könnte. Ich würde empfehlen, bei den beiden anderen Vorschlägen zu bleiben.
Moshe
2

Wenn Sie hauptsächlich lesen (und nur wenige Updates), gibt es wirklich keinen Grund, nicht alles zu indizieren, was Sie zum Indizieren benötigen. Wenn Sie häufig aktualisieren, müssen Sie möglicherweise vorsichtig sein, wie viele Indizes Sie haben. Es gibt keine feste Zahl, aber Sie werden feststellen, wenn sich die Dinge verlangsamen. Stellen Sie sicher, dass Ihr Clustered-Index auf der Grundlage der Daten am sinnvollsten ist.

Bob King
quelle
2

Eine Sache, die Sie in Betracht ziehen können, ist das Erstellen von Indizes für eine Standardkombination von Suchvorgängen. Wenn Spalte1 häufig durchsucht wird und Spalte2 häufig damit verwendet wird und Spalte3 manchmal mit Spalte2 und Spalte1 verwendet wird, kann ein Index für Spalte1, Spalte2 und Spalte3 in dieser Reihenfolge für jeden dieser drei Umstände verwendet werden Nur ein Index muss gepflegt werden.

Jeffrey L Whitledge
quelle
2

Ein Index verursacht Kosten, wenn die zugrunde liegende Tabelle aktualisiert wird. Ein Index bietet einen Vorteil, wenn er zum Schließen einer Abfrage verwendet wird. Für jeden Index müssen Sie die Kosten gegen den Nutzen abwägen. Wie viel langsamer läuft die Abfrage ohne den Index? Wie viel Nutzen läuft schneller? Können Sie oder Ihre Benutzer die langsame Geschwindigkeit tolerieren, wenn der Index fehlt?

Können Sie die zusätzliche Zeit tolerieren, die zum Abschließen eines Updates erforderlich ist?

Sie müssen Kosten und Nutzen vergleichen. Das ist speziell für Ihre Situation. Es gibt keine magische Anzahl von Indizes, die die Schwelle von "zu vielen" überschreiten.

Es gibt auch die Kosten für den Speicherplatz, der zum Speichern des Index benötigt wird, aber Sie haben gesagt, dass dies in Ihrer Situation kein Problem darstellt. Dasselbe gilt in den meisten Situationen, wenn man bedenkt, wie billig Speicherplatz geworden ist.

Walter Mitty
quelle
1

Wie viele Spalten gibt es? Mir wurde immer gesagt, ich solle einspaltige Indizes erstellen, keine mehrspaltigen Indizes. Also nicht mehr Indizes als die Anzahl der Spalten, IMHO.

Lamcro
quelle
1

Es kommt wirklich darauf an, keinen Index hinzuzufügen, es sei denn, Sie wissen (und dies bedeutet häufig das Sammeln von Nutzungsstatistiken), dass er weitaus häufiger verwendet wird als aktualisiert.

Jeder Index, der diese Kriterien nicht erfüllt, kostet Sie mehr für die Neuerstellung als die Leistungseinbuße, wenn Sie ihn in dem seltsamen Fall, in dem er verwendet wurde, nicht haben.

Torbjörn Gyllebring
quelle
1

Der SQL Server bietet Ihnen einige gute Tools, mit denen Sie sehen können, welche Indizes tatsächlich verwendet werden. Dieser Artikel, http://www.mssqltips.com/tip.asp?tip=1239 , enthält einige Abfragen, mit denen Sie einen besseren Einblick in die Verwendung eines Index im Gegensatz zur Aktualisierung erhalten.

aboy021
quelle
0

Es basiert vollständig auf den Spalten, die in der Where-Klausel verwendet werden. Und als Daumen der Regel müssen wir Indizes für Fremdschlüsselspalten haben, um DEADLOCKS zu vermeiden. Der AWR-Bericht sollte regelmäßig analysiert werden, um die Notwendigkeit von Indizes zu verstehen.

P Sharma
quelle
2
Indizes für Fremdschlüsselspalten, um Deadlocks zu vermeiden? Haben Sie eine Referenz, die erklärt, warum und wie dies der Fall ist?
Jay Sullivan