Indizierung von Anfang an oder wenn Leistungsprobleme auftreten?

15

Meine Frage betrifft die Verwendung von Indizes.

  1. Soll ich von Anfang an mit der Indizierung beginnen oder wenn Leistungsprobleme auftreten?

  2. Wir können auch einen temporären Index erstellen, während eine Abfrage ausgeführt wird. Was sind die Vor- und Nachteile solcher Techniken?

codecool
quelle

Antworten:

17

Soll ich von Anfang an mit der Indizierung beginnen oder wenn Leistungsprobleme auftreten?

Die Indizierungsstrategie entwickelt sich tendenziell mit dem Auftreten von Nutzungsmustern. Es gibt jedoch auch Strategien und Gestaltungsrichtlinien, die im Vorfeld angewendet werden können.

  • Wählen Sie einen guten Clustering-Schlüssel . Normalerweise können Sie den geeigneten Clustered-Index zur Entwurfszeit anhand des erwarteten Musters von Einfügungen in eine Tabelle ermitteln. Wenn ein zwingender Fall für eine Veränderung in der Zukunft auftaucht, so sei es.

  • Erstellen Sie Ihre primären und andere eindeutige Einschränkungen . Diese werden durch eindeutige Indizes erzwungen.

  • Erstellen Sie Ihre Fremdschlüssel und die zugehörigen nicht gruppierten Indizes . Fremdschlüssel sind die Join-Spalten, auf die am häufigsten verwiesen wird. Indizieren Sie sie daher von Anfang an.

  • Erstellen Sie Indizes für offensichtlich sehr selektive Abfragen . Bei Abfragemustern, von denen Sie bereits wissen, ist die Auswahl sehr hoch und es ist wahrscheinlich, dass Lookups anstelle von Scans verwendet werden.

Darüber hinaus sollten Sie bei der Implementierung neuer Indizes schrittweise und ganzheitlich vorgehen. Mit ganzheitlich meine ich, den potenziellen Nutzen und die Auswirkung auf alle Abfragen und vorhandenen Indizes bei der Bewertung eines Zusatzes zu bewerten.

Ein nicht seltenes Problem in SQL Server-Kreisen ist die Überindizierung, die sich aus den fehlenden Index-DMVs und SSMS-Hinweisen ergibt. Keines dieser Tools wertet vorhandene Indizes aus und empfiehlt Ihnen fröhlich, einen neuen 6-Spalten-Index zu erstellen, anstatt eine einzelne Spalte zu einem vorhandenen 5-Spalten-Index hinzuzufügen.

-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
)

-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

Kimberly Tripp hat einige exzellente Informationen zur Indizierungsstrategie, die sich auf andere Plattformen anwenden lassen, während sich SQL darauf konzentriert. Für die SQL Server-Leute gibt es einige nützliche Tools zum Identifizieren von Duplikaten, wie im obigen Beispiel.

Wir können auch einen temporären Index erstellen, während eine Abfrage ausgeführt wird. Was sind die Vor- und Nachteile solcher Techniken?

Dies gilt normalerweise nur für selten ausgeführte Abfragen, normalerweise ETL. Sie müssen bewerten:

  1. Verringert die zum Erstellen des Index benötigte Zeit die Ausführungszeit der Abfrage?
  2. Übersteigt der Wartungsaufwand für das Belassen des Index die Zeit, die zum Erstellen / Löschen bei Bedarf benötigt wird?
Mark Storey-Smith
quelle
3
+1 Clustering Key, Foreign Key, Unique / Primary Key und nicht vertrauenswürdige fehlende Index-DMVs zum Nennwert ... All diese Dinge sind gute Ratschläge. Der Umgang mit vorhandenen Indizes ist in SQL Server mit der DMV sys.dm_db_index_usage_stats ziemlich einfach zu überwachen. Über einen bestimmten Zeitraum können Sie Indizes auflisten, die nicht gescannt oder durchsucht wurden, und gleichzeitig feststellen, dass dieselben Indizes mehrmals aktualisiert wurden. Dies weist auf eine Überindizierung hin.
Matt M
1
+1, jedoch 'Indizes für offensichtlich hochselektive Abfragen erstellen'. deckt nicht alle anderen Szenarien ab. Mithilfe von Indizes können Sie die Ergebnisse sortieren, auch wenn Ihre Abfragen nicht sehr selektiv sind. Sie können auch Abfragen beschleunigen, wenn sie alle ausgewählten Spalten abdecken.
Unbilliger
1
Einverstanden, aber die Frage war eher nach einem Startpunkt als nach dem Endspiel zu suchen. Das Identifizieren von zu behandelnden Abfragen ist ohne Verwendungsmuster schwierig, da Sie sie selten alle abdecken können.
Mark Storey-Smith
8

Beide Ansätze bergen Risiken:

Option a) Index von Anfang an, aber Sie wissen nicht, dass Sie eine Reihe von Indizes erstellt haben, die niemals verwendet werden. Dies erhöht den Aufwand (am deutlichsten bei Abfragen, die Daten ändern, aber auch bei der Optimierung von SELECT-Anweisungen, die versuchen, den besten Index zu ermitteln).

Sie müssen sich disziplinieren, um Indizes zu identifizieren, die nicht mehr verwendet werden, und versuchen, diese zu entfernen (PostgreSQL kann dies; leider ist MySQL im Vergleich dazu aus der Box sehr schwach.)

Option b) Fügen Sie erst Indizes hinzu, wenn sich andere beschweren oder wenn Ihre Diagnosetools dazu führen, dass bestimmte Abfragen langsam sind und verbessert werden könnten.

Das Risiko, das Sie einführen, besteht darin, dass Sie zwischen dem Zeitpunkt, zu dem Sie feststellen, dass Sie den Index benötigen, und dem Zeitpunkt, zu dem Sie ihn hinzufügen müssen, nicht genügend Zeit haben.

PostgreSQL unterstützt das Erstellen von Indizes CONCURRENTLY, wodurch die Belastung durch diese Anforderung zum plötzlichen Hinzufügen von Indizes zwar etwas verringert wird , das Handbuch enthält jedoch einige Einschränkungen .


Option (b) ist in der Regel meine Präferenz, aber ich denke, eine Mischung aus beiden Optionen ist wahrscheinlich die beste Lösung. Es hängt von Ihrem Konfidenzniveau ab, ob Sie glauben, dass ein Index tatsächlich verwendet wird.

Was dies zu einer besonders komplexen Diskussion macht, ist, dass es normalerweise einfach ist, Indizes zu ändern, aber es ist schwieriger, das Schema zu ändern. Ich möchte die verzögerte Reaktion von b nicht als Entschuldigung für Rücksichtslosigkeit fördern .

Morgan Tocker
quelle
4

Neben Marks Antwort

Sie können ein Gefühl dafür bekommen, wenn Sie realistische Testdaten bei erwarteten Mengen haben. Ich habe viele, viele (zu viele) Fälle gesehen, in denen eine Abfrage mit 1000 Zeilen, aber nicht mit der Million in der Produktion einwandfrei ausgeführt wird.

Wenn Sie können, arbeiten Sie später an einer Kopie der Produktion,

Natürlich habe ich das seltsame Problem nur in der Produktion gesehen, weil die Nutzungsmuster so sind, dass alles andere identisch ist

Temporäre Indizes? Außerhalb von ETL-Lademustern benötigen Sie sie erneut, wenn Sie sie einmal benötigen. Vergiss nicht: Ein Index erstellen / löschen ist ein Schreiben und wird protokolliert = mehr laden

gbn
quelle
3

Nur um ein paar Dinge hinzuzufügen.

  • Temporäre Indizes sind eine schreckliche Idee. Es sei denn, der Index befindet sich in einer temporären Tabelle.
  • Indizes belegen viel mehr Datenraum (und auch mehr Overhead), als die Benutzer erkennen. Erstellen Sie sie daher konservativ.

Das ist mein Ansatz.

  1. Ähnlich wie bei Mark sollten Sie Indizes dort erstellen, wo sie sinnvoll sind, aber nicht überfällig.
  2. Sie müssen nicht warten, bis die Leistung nachlässt, um neue Indizes zu erstellen. Wenn Sie neues SQL schreiben, führen Sie einen Abfrageplan aus (vorzugsweise für Ihre Produktdatenbank). Sie sollten sehen können, ob ein neuer Index erforderlich ist.
  3. Haben Sie keine Angst, > 0oder > ""in Ihre Where- Klauseln für nicht verwendete Spalten zu setzen.

    1. Nehmen wir also an, Sie haben einen Index für A, B, C und D. Sie haben jedoch nur die Informationen A, B, D. Es gibt keinen Grund, warum Sie nicht
    select * from blah 
    where A="one" 
    and B="two" 
    and C>=""     --to match index
    and D="four"
    
    --This will use your existing index. No need to create a redundant one.
user606723
quelle
Eine andere Sache, dies ist im "dba" -Forum, aber die Indexerstellung sollte wirklich in der Verantwortung des Entwicklers liegen, nicht in der der dba. (Für Fälle, in denen sie vollständig getrennt sind.)
user606723
2
Ihre Aussage bezüglich des von Indizes belegten Speicherplatzes ist ein wenig irreführend, da ein nicht gruppierter Index nur einen geringen Overhead verursacht. Wenn Sie eine Frage zu diesem Punkt stellen könnten, lohnt es sich, die Sache weiter zu untersuchen. Zweitens stimme ich nicht zu, dass die Indexerstellung die Domäne des Entwicklers ist. Dies ist einer der Bereiche, in denen die Zusammenarbeit zwischen Entwickler und DBA die besten Ergebnisse erzielen kann.
Mark Storey-Smith
1
Ich werde Ihnen ein Beispiel für einen unserer Tische geben. Tischgröße: 21052404 KB. Größe eines nicht gruppierten Index für diese Tabelle: 6637470 KB. Sehr wenig Aufwand? Ich denke nicht. Außerdem sage ich nicht, dass mit den Datenbankadministratoren nicht zusammengearbeitet werden sollte, sondern dass es in der Verantwortung des Entwicklers liegen sollte, zu bestimmen, ob ein neuer Index erstellt werden muss. Sie sollten kein SQL schreiben und erwarten, dass das dbas dies selbst herausfindet.
user606723
1
Ohne Kontext kann man solche Zahlen nicht zitieren. Ohne Angabe der NC-Indexspalten und des Clusterschlüssels ist es unmöglich, das Verhältnis von Overhead zu Daten zu berechnen.
Mark Storey-Smith
Touche. Der Schlüssel ist ein [numerisch (24), Zeichen, Datum] und die NC-Spalten sind [Datum, numerisch (24)]. (Nur zwei Spalten in diesem speziellen Index).
user606723
2

Ich werde versuchen, nur die erste Frage zu beantworten. Wenn Sie ungefähr von Anfang an abschätzen können, wie viele Datensätze Sie nach einer bestimmten Zeit in Ihren Tabellen haben, ist es besser, von Anfang an mit dem Entwerfen einiger Indizes zu beginnen. Versuchen Sie, einige Testtools oder Testskripts zu verwenden, die so viele Aufrufe wie möglich für die Anwendungsaufrufe automatisieren, von denen Sie glauben, dass sie am häufigsten verwendet werden, und Sie werden sehen, welche Tabellenscans von Anfang an vermieden werden können.

Am Anfang wird es eine Vermutung sein, aber mit der Zeit, wenn Sie die richtigen Nutzungsstatistiken haben, werden Sie ein klareres Bild haben.

Marian
quelle