it-swarm-eu.dev

Best Practices für Datenbankindizes

Was sind einige DOs und DONTs zur Verbesserung der Datenbankleistung mithilfe von Index?

Ein DO wäre ein Fall, in dem ein Index erstellt werden sollte, oder ein anderer indexbezogener Tipp, der die Leistung verbessert.

Ein DONT ist ein Fall, in dem kein Index erstellt werden sollte oder eine andere indexbezogene Aktion, die die Leistung beeinträchtigen kann.

17
Click Upvote

Dies hängt teilweise davon ab, wofür die Datenbank verwendet werden soll, da Indizes im Allgemeinen Einfügungen und Aktualisierungen verlangsamen und Abfragen beschleunigen. In einem Data Warehouse gibt es im Allgemeinen keine Aktualisierungen und Batch-Einfügungen, was das Erstellen von Indizes erleichtert, sowie viele, viele Abfragen, die mit vielen Indizes beschleunigt werden. In einer Online-Datenbank für Webverkäufe und dergleichen gibt es viele Einfügungen und Aktualisierungen. Wenn Sie also mehr als ein paar sorgfältig ausgewählte Indizes haben, wird dies nur verlangsamt.

Wenn Sie viele Abfragen eines bestimmten Typs erhalten, können Sie einen Index für die Abfrage erstellen, obwohl dies eher für die Online-Verarbeitung als für Data Warehouses gilt. Wenn bestimmte Spalten in Abfragen häufig vorkommen, möchten Sie möglicherweise einen Index für diese Spalte. Dies ist besonders nützlich für Data Warehouses, die auf viele verschiedene und oft unvorhersehbare Arten abgefragt werden.

Versuchen Sie beim Hinzufügen oder Entfernen eines Index, einen Leistungstest durchzuführen, um festzustellen, welche Auswirkungen er hat. Ohne das schießt du blind.

Es gibt Bücher zum Optimieren von Abfragen und Datenbanken, die häufig für ein Datenbanksystem spezifisch sind und die Tools dieses RDBMS verwenden. Wenn Sie jedoch feststellen, dass Sie die Datenbank stark optimieren müssen, führen Sie einen großen Vorgang aus und sollten wahrscheinlich einen DBA mit entsprechendem Fachwissen einstellen.

15
David Thornley

Es hängt stark davon ab, wie Sie Ihre Tabellen verwenden. Es gibt keine einfache Antwort.

Der beste Rat, den ich Ihnen geben kann, ist: Verwenden Sie einen Tuning-Berater . Sie analysieren die Datenbankbefehle, während Sie die Anwendung verwenden, und führen dann Auslastungstests durch, um Ihnen aussagekräftige Hinweise zu geben.

Sie existieren für SQL Server & Oracle . Ich weiß nicht, ob andere DBMS sie haben, nur bezweifle ich, dass sie solche grundlegenden Tools nicht bieten.

Einige zufällige Empfehlungen:

  • Indizes bieten hohe Leistungssteigerungen, wenn sie auf Spalten angewendet werden, die häufig in der WHERE-Klausel enthalten sind
  • Verwenden Sie den Clustered-Index für die am häufigsten verwendete Spalte in Ihren Abfragen.
  • Vergessen Sie nicht, dass Sie mehrere Indizes mit einer Kombination von Spalten erstellen können (wie sie in Ihren Abfragen verwendet werden).
  • Wenn viele Indizes vorhanden sind, wird die Leistung von INSERT-Befehlen verringert.

Letzter Rat: Wenn die DB-Leistungen für Ihr Projekt wirklich wichtig sind, stellen Sie einen Spezialisten ein. Das habe ich getan.

17
user2567

@Pierre 303 hat es bereits gesagt, aber ich werde es noch einmal sagen. DO Indizes für Spaltenkombinationen verwenden. Ein kombinierter Index für (a, b) Ist für Abfragen für a nur geringfügig langsamer als ein Index für a allein und ist massiv besser, wenn Ihre Abfrage beide Spalten kombiniert. Einige Datenbanken können Indizes für a und b verknüpfen, bevor sie in die Tabelle aufgenommen werden. Dies ist jedoch bei weitem nicht so gut wie ein kombinierter Index. Wenn Sie einen kombinierten Index erstellen, sollten Sie die Spalte, die am wahrscheinlichsten durchsucht wird, zuerst in den kombinierten Index einfügen.

Wenn Ihre Datenbank dies unterstützt, setzen Sie [~ # ~] [~ # ~] Indizes für Funktionen, die in Abfragen und nicht in Spalten angezeigt werden. (Wenn Sie eine Funktion für eine Spalte aufrufen, sind Indizes für diese Spalte unbrauchbar.)

Wenn Sie eine Datenbank mit echten temporären Tabellen verwenden, die Sie im laufenden Betrieb erstellen und zerstören können (z. B. PostgreSQL, MySQL, aber nicht Oracle), dann DO Indizes für temporäre Tabellen erstellen.

Wenn Sie eine Datenbank verwenden, die dies zulässt (z. B. Oracle), sperren Sie DO gute Abfragepläne ein. Abfrageoptimierer ändern im Laufe der Zeit die Abfragepläne. Sie verbessern normalerweise den Plan. Aber manchmal machen sie es dramatisch schlimmer. Sie werden Planverbesserungen im Allgemeinen nicht wirklich bemerken - die Abfrage war kein Engpass. Aber ein einziger schlechter Plan kann eine geschäftige Site zum Erliegen bringen.

NICHT Indizes für Tabellen haben, für die Sie eine große Datenlast ausführen möchten. Es ist viel, viel schneller, Indizes zu löschen, die Daten zu laden und dann die Indizes neu zu erstellen, als sie beim Laden der Tabelle zu verwalten.

NICHT Verwenden Sie Indizes für Abfragen, die auf mehr als einen kleinen Bruchteil einer großen Tabelle zugreifen müssen. (Wie klein die Hardware ist, hängt von der Hardware ab. 5% sind eine anständige Faustregel.) Wenn Sie beispielsweise Daten mit Namen und Geschlecht haben, sind Namen ein guter Kandidat für die Indizierung, da jeder Name einen kleinen Bruchteil der gesamten Zeilen darstellt. Es wäre nicht hilfreich, nach Geschlecht zu indizieren, da Sie immer noch auf 50% der Zeilen zugreifen müssen. Sie möchten stattdessen wirklich einen vollständigen Tabellenscan verwenden. Der Grund dafür ist, dass Indizes zufällig auf eine große Datei zugreifen und Sie daher nach Festplatten suchen müssen. Festplattensuchen sind langsam. Als Beispiel habe ich kürzlich eine einstündige Abfrage beschleunigt, die so aussah:

SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
  JOIN big_table
    ON big_table.small_table_id = small_table.id
GROUP BY small_table.id

bis unter 3 Minuten durch Umschreiben wie folgt:

SELECT small_table.id, big_table_summary.summed_value
FROM small_table
  JOIN (
      SELECT small_table_id, SUM(some_value) as summed_value
      FROM big_table
      GROUP BY small_table_id
    ) big_table_summary
    ON big_table_summary.small_table_id =  small_table.id

dies zwang die Datenbank zu verstehen, dass sie nicht versuchen sollte, den verlockenden Index für big_table.small_table_id zu verwenden. (Eine gute Datenbank wie Oracle sollte das selbst herausfinden. Diese Abfrage wurde unter MySQL ausgeführt.)

pdate : Hier ist eine Erklärung des von mir gemachten Festplatten-Suchpunkts. Ein Index gibt einen schnellen Überblick darüber, wo sich die Daten in der Tabelle befinden. Dies ist normalerweise ein Gewinn, da Sie nur die Daten betrachten, die Sie betrachten müssen. Aber nicht immer, besonders wenn Sie sich irgendwann viele Daten ansehen werden. Festplatten streamen Daten gut, aber machen Suchvorgänge langsam. Eine zufällige Suche nach Daten auf der Festplatte dauert eine 1/200stel Sekunde. Die langsame Version der Abfrage hat ungefähr 600.000 davon ausgeführt und fast eine Stunde gedauert. (Es wurden mehr Suchvorgänge durchgeführt, aber das Caching hat einige davon erfasst.) Im Gegensatz dazu wusste die schnelle Version, dass sie alles lesen und Daten mit etwa 70 MB/Sekunde streamen musste. Es kam in weniger als 3 Minuten durch einen 11-GB-Tisch.

4
btilly

Grundsätzlich beschleunigen Indizes die Suche, verlangsamen jedoch das Schreiben und beanspruchen Platz. Das ist der Kompromiss.

Jedes Feld, das häufig zum Beitreten, Suchen/Vergleichen oder Bestellen nach verwendet wird, ist ein Kandidat für einen Index. Um zu wissen, dass es wirklich nützlich ist, messen Sie. Die Fremdschlüssel von stark verknüpften Tabellen mit vielen (> 1000) Datensätzen und wenigen Einfügungen zahlen sich jedoch aus.

Bei Textfeldern können Sie einen Teil des Felds indizieren (z. B. die ersten 6 Zeichen). Dies würde Ihre Abfrage beschleunigen, aber die Indizes entlasten. Die Volltextsuche (Suche nach like %substring%) Erfordert verschiedene Techniken, mit denen ich nicht vertraut bin, daher kann ich Ihnen dort keine Ratschläge geben.

Eine wichtige Situation, in der Indizes nicht helfen: Sie können den Index der vollständigen Datums- oder Datums-/Uhrzeitfelder nicht verwenden, wenn Sie einen Teil des Datums suchen (/ join/order). Ein Index für date_created Hilft Ihnen bei einer Abfrage wie select * from t where year(date_created) = 2011 nicht. In MySQL können Sie für einen Teil des Datums keinen Index erstellen. (Wenn Sie 'between' anstelle von year() verwenden, kann der Index für das Datumsfeld verwendet werden.)

Weitere Informationen zu MYSQL finden Sie im Handbuch: http://dev.mysql.com/doc/refman/5.6/en/optimization-indexes.html

2
Inca

DO: Indizieren Sie die wenigen Felder, auf die Sie durch Abfrage und/oder Vergleich am häufigsten zugreifen.

NICHT: Indizieren Sie jedes Feld in der Tabelle, um es schneller zu machen.

Ich habe keine Statistiken darüber, aber ich versuche, nicht mehr als 4 indizierte Felder in einer Tabelle zu behalten, wenn ich helfen kann. Das Normalisieren meiner Datenbanken hilft normalerweise dabei, diese Zahlen niedrig zu halten, da alles mit einem numerischen Schlüssel durchsucht werden kann (was sowieso schneller ist). Ich versuche, mich für die Indizierung von Volltextfeldern fernzuhalten. Sie sind ziemlich schwer.

2
Joel Etherton

DO: Versuchen Sie, die Gesamtgröße des Clustered-Index auf ein Minimum zu beschränken. Die Clustered-Index-Einträge werden in andere nicht-Clustered-Indizes aufgenommen, und ab hier besteht die Möglichkeit, dass Speicherplatz verschwendet wird.

1
user8685

Stellen Sie sich eine Tabelle als Lexikon vor, in dem die Artikel nach Erscheinungsreihenfolge (oder überhaupt keine hilfreiche Reihenfolge) sortiert sind, und einen Tabellenindex als Buchindex für dieses Lexikon.

Sie verwenden einen Index, um schnell etwas in einem Buch zu finden. Anstatt das gesamte Buch zu scannen, müssen Sie nur den Schlüssel im Index finden (ein Index wird normalerweise irgendwie sortiert (nach Kategorie, wissenschaftlichem Bereich, historischer Epoche usw.). Dies bedeutet auch, dass Sie nicht scannen müssen den gesamten Index) und springen dann zur rechten Seite.

Im Gegensatz zu einem Buch wird eine Tabelle jedoch nicht einmal gedruckt und ist dann unveränderlich. Es wird ständig aktualisiert, und daher muss jeder Index damit aktualisiert werden. Dies ist natürlich mit räumlichen und zeitlichen Kosten verbunden, die nur durch die Nützlichkeit eines Index gerechtfertigt werden können.

Verwenden Sie also einen Index für eine Spalte, wenn diese Spalte als Schlüssel für häufige Suchanfragen verwendet wird, und verwenden Sie keinen, wenn dies nicht der Fall ist. Das Wort häufig ist im Allgemeinen ein so guter Quantifizierer wie es nur geht. Am Ende müssen Sie eine gute Schätzung vornehmen, welche häufig sind, und dann im Zweifelsfall einfach die Performance mit oder ohne Index bewerten.

1
back2dos