2010-09-21 8 views
7

Für Argumente, sagen wir, es ist für SQL 2005/8. Ich verstehe, dass wenn Sie Indizes für eine Tabelle setzen, um SELECT Anweisungen abzustimmen, diese Indizes während INSERT/UPDATE/DELETE Aktionen beibehalten müssen.Wann verwaltet MS-SQL Tabellenindizes?

Meine Hauptfrage ist diese:

Wann wird SQL Server Indizes einer Tabelle halten?

ich viele nachfolgende Fragen:

Ich gehe davon aus, dass es naiv so tun wird, nachdem ein Befehl ausgeführt wurde. Angenommen, Sie fügen 20 Zeilen ein, wird der Index beibehalten, nachdem 20 Zeilen eingefügt und festgeschrieben wurden.

  • Was in der Situation passiert, wo ein Skript mehrere Anweisungen gegen eine Tabelle verfügt, sind aber ansonsten eindeutige Aussagen?

  • Hat der Server die Intelligenz den Index zu halten, nachdem alle Anweisungen ausgeführt werden oder es es tut pro Aussage?

Ich habe Situationen erlebt, in denen Indizes gelöscht werden und neu erstellt, nachdem groß/viele INSERT/UPDATE Aktionen.

  • Das vermutlich verursacht Wiederaufbau die Indizes der gesamten Tabelle, auch wenn Sie nur eine Handvoll Zeilen ändern?

  • Würde ein Leistungsvorteil bei dem Versuch, es zu sammeln INSERT und UPDATE Aktionen in eine größere Charge, sagen durch Reihen zu sammeln in einer temporären Tabelle einzufügen, im Gegensatz zu viele kleineren Einsätze zu tun?

  • Wie wäre es, wenn die oben stehenden Zeilen verglichen werden, statt einen Index fallen zu lassen, statt den Wartungstreffer zu nehmen?
  • Sorry für die Verbreitung von Fragen - es ist etwas, von dem ich immer weiß, dass es bewusst ist, aber wenn ich versuche, ein Skript zu tunen, um ein Gleichgewicht zu finden, ich weiß nicht, wann Index Wartung auftritt.

    Edit: Ich verstehe, dass Leistungsfragen weitgehend von der Menge der Daten während der Einfügung/Aktualisierung und der Anzahl der Indizes abhängen. Wiederum um Argumente willen, hätte ich zwei Situationen:

  • Ein Index schweren Tisch abgestimmt für wählt.
  • Ein Index Leuchttisch (PK).

Beide Situationen hätten eine große Einfüge-/Aktualisierungsgruppe, z. B. 10k + Zeilen.

Bearbeiten 2: Ich bin mir bewusst, in der Lage, ein bestimmtes Skript auf einem Datensatz zu profilieren. Das Profiling sagt mir jedoch nicht, warum ein bestimmter Ansatz schneller ist als ein anderer. Ich interessiere mich mehr für die Theorie hinter den Indizes und wo Performance-Probleme auftreten, keine definitive Antwort "das ist schneller als das".

Danke.

+0

Gute Frage. Für den zweiten Teil hängt es vollständig von der Anzahl und dem Inhalt der Indizes ab, ob es schneller fällt und neu erstellt oder nur über den Indizes aktualisiert wird. Wie die meisten Dinge in SQL gibt es keine Antwort oder Methode, die zu 100% korrekt ist. – JNK

+0

@JNK Ich vermutete genauso viel, ich hoffe, jemand kann die Situation im Ballpark ablegen oder erklären, in welchen Situationen ein bestimmter Ansatz teuer wird. –

Antwort

3

Wenn Ihre Anweisung (nicht einmal Transaktion) abgeschlossen ist, sind alle Ihre Indizes auf dem neuesten Stand. Wenn Sie ein Commit durchführen, werden alle Änderungen dauerhaft und alle Sperren werden freigegeben. Andernfalls wäre es keine "Intelligenz", es würde die Integrität verletzen und möglicherweise Fehler verursachen.

Edit: von "Integrität" Ich meine das: einmal begangen, sollten die Daten sofort für jedermann verfügbar sein. Wenn die Indizes zu diesem Zeitpunkt nicht aktuell sind, kann dies zu falschen Ergebnissen führen.

Wenn Sie die Batch-Größe erhöhen, verbessert sich Ihre Leistung ursprünglich, dann wird es langsamer. Sie müssen Ihre eigenen Benchmarks ausführen und Ihre optimale Batchgröße ermitteln. In ähnlicher Weise müssen Sie einen Benchmark durchführen, um festzustellen, ob Indizes schneller gelöscht/neu erstellt werden können oder nicht.

Bearbeiten: Wenn Sie Stapel von Zeilen in einer Anweisung einfügen/aktualisieren/löschen, werden Ihre Indizes einmal pro Anweisung geändert. Das folgende Skript demonstriert das:

CREATE TABLE dbo.Num(n INT NOT NULL PRIMARY KEY); 
GO 
INSERT INTO dbo.Num(n) 
SELECT 0 
UNION ALL 
SELECT 1; 
GO 
-- 0 updates to 1, 1 updates to 0 
UPDATE dbo.Num SET n = 1-n; 
GO 
-- doing it row by row would fail no matter how you do it 
UPDATE dbo.Num SET n = 1-n WHERE n=0; 
UPDATE dbo.Num SET n = 1-n WHERE n=1; 
+0

Ich hätte gedacht, dass die Datenintegrität nicht für einen Index gilt. Ist dies nur bei eindeutigen Einschränkungen der Fall? –

+0

Wenn der Index keine Integrität hat, ist er ziemlich nutzlos. Ich bin mir nicht sicher, was passieren würde, wenn SQL einen Index verwenden würde, um einen Datensatz zu finden, der dort sein sollte, aber dieser Datensatz nicht war. Ich schätze, Sie würden falsche Negative bekommen, was den Zweck von ACID ziemlich besiegt. – JNK

+0

So wird der Index auf einer Zeile beibehalten, wie die Werte eingefügt/aktualisiert werden? Das heißt, sie landen automatisch auf der Grundlage beliebiger Indizes am richtigen Ort, und die Indizes werden bei Bedarf geändert. Selbst wenn Reiheneinsätze zusammengefügt werden, sollte kein Unterschied zu mehreren kleineren Einsätzen erkennbar sein. Ich denke, es gibt einen Overhead mit festgeschriebenen Indexänderungen und Tabellensperren ... –