2008-08-26 2 views
14

Ich habe einen Sproc, der 750K Datensätze in eine temporäre Tabelle durch eine Abfrage als eine seiner ersten Aktionen legt. Wenn ich Indizes für die temporäre Tabelle erzeuge, bevor sie gefüllt wird, dauert die Ausführung des Elements etwa doppelt so lange wie beim Indexieren nach dem Füllen der Tabelle. (Der Index ist eine ganze Zahl in einer einzigen Spalte, die indizierte Tabelle ist nur zwei Spalten, jede einzelne ganze Zahl.)Warum funktioniert SQL Server schneller, wenn Sie eine Tabelle nach dem Ausfüllen indizieren?

Das scheint mir ein wenig aus, aber dann habe ich nicht das beste Verständnis von dem, was geht unter der Haube. Hat jemand eine Antwort dafür?

Antwort

1

dies, weil, wenn die Daten, die Sie einfügen nicht in der Reihenfolge des Index ist, wird SQL Seiten aufgeteilt haben, um zusätzliche Zeilen, um Platz für sie zu halten zusammen logisch

2

Sie sollten einen Index NEVER EVER erstellen auf eine leere Tabelle, wenn Sie sie anschließend direkt massiv laden wollen. Indizes müssen beibehalten werden, da sich die Daten in der Tabelle ändern. Stellen Sie sich also so vor, als würde für jeden Insert der Tabelle der Index neu berechnet (was eine teure Operation ist). Laden Sie zuerst die Tabelle und erstellen Sie den Index, nachdem Sie die Belastung beendet haben. Das war der Leistungsunterschied wird.

2

Nach der Durchführung großer Datenmanipulationsoperationen müssen Sie häufig die zugrunde liegenden Indizes aktualisieren. Sie können dies tun, indem Sie die Anweisung UPDATE STATISTICS [table] verwenden.

Die andere Option besteht darin, den Index zu löschen und neu zu erstellen. Wenn Sie große Daten einfügen, werden die Einfügungen wahrscheinlich schneller ausgeführt. Sie können dies sogar in Ihre gespeicherte Prozedur integrieren.

41

Wenn Sie einen gruppierten Index erstellen, wirkt sich dies auf die Art und Weise aus, in der die Daten physisch auf der Festplatte geordnet sind. Es ist besser, den Index nachträglich hinzuzufügen und das Datenbankmodul die Zeilen neu anordnen zu lassen, wenn es weiß, wie die Daten verteilt sind.

Nehmen wir zum Beispiel an, Sie müssten eine Ziegelmauer mit nummerierten Steinen bauen, so dass die mit der höchsten Nummer am unteren Rand der Mauer stehen. Es wäre eine schwierige Aufgabe, wenn man die Steine ​​nur zufällig in zufälliger Reihenfolge übergeben würde - man würde nicht wissen, welche Steine ​​sich als die höchsten Zahlen herausstellen würden, und man müsste die Mauer niederreißen und baue es wieder und wieder auf. Es wäre viel einfacher, diese Aufgabe zu bewältigen, wenn Sie alle Steine ​​vor sich hätten und Ihre Arbeit organisieren könnten.

So ist es für die Datenbank-Engine - wenn Sie es über den gesamten Job wissen lassen, kann es viel effizienter sein, als wenn Sie es nur Zeile für Zeile füttern.

+2

Sehr gutes Beispiel +1 –

+0

Super Analogie, danke! –

6

Dies liegt daran, dass der Datenbankserver Berechnungen jedes Mal durchführen muss, wenn Sie eine neue Zeile einfügen. Grundsätzlich endet die Neuindizierung der Tabelle jedes Mal. Es scheint nicht eine sehr teure Operation zu sein, und das ist es auch nicht, aber wenn man so viele davon zusammen macht, beginnt man, die Auswirkungen zu sehen. Deshalb möchten Sie normalerweise nach dem Auffüllen Ihrer Zeilen indexieren, da dies nur einmalige Kosten verursacht.

1

Aufgrund der Tatsache, dass, wenn SQL Server Tabellen mit Daten indiziert, ist es in der Lage, genaue Statistiken von Werten in indizierten Spalte zu erzeugen. In einigen Momenten wird SQL Server Statistiken neu berechnen, aber wenn Sie massive Einfügungen durchführen, kann sich die Verteilung der Werte ändern, nachdem die Statistik das letzte Mal berechnet wurde.

Die Tatsache, dass Statistiken veraltet sind, kann im Query Analyzer ermittelt werden. Wenn Sie sehen, dass sich bei einer bestimmten Tabellensuche die Anzahl der erwarteten Zeilen stark von der tatsächlichen Anzahl der verarbeiteten Zeilen unterscheidet.

Sie sollten UPDATE STATISTICS verwenden, um die Verteilung der Werte neu zu berechnen, nachdem Sie alle Daten eingefügt haben. Danach sollte kein Leistungsunterschied mehr beobachtet werden.

3

Denken Sie auf diese Weise.

Gegeben
unorderedList = {5, 1,3}
orderedlist = {1,3,5}

2 In den beiden Listen.
unorderedList = {5, 1,3,2}
orderedlist = {1,2,3,5}

Welche Liste denken Sie, ist einfacher zu hinzufügen?

Btw Bestellung Ihrer Eingabe vor der Belastung wird Ihnen einen Schub geben.

1

Wenn Sie einen Index für eine Tabelle haben, müssen Sie beim Hinzufügen von Daten zur Tabelle die Tabelle neu sortieren, um Platz für die neuen Datensätze an der entsprechenden Stelle zu schaffen. Wenn Sie viele Daten hinzufügen, müssen Sie sie immer wieder neu anordnen. Wenn Sie einen Index erst nach dem Laden der Daten erstellen, muss die Neubestellung nur einmal durchgeführt werden.

Natürlich, wenn Sie die Datensätze in Indexreihenfolge importieren, sollte es nicht so viel ausmachen.

1

Zusätzlich zum Index-Overhead ist das Ausführen jeder Abfrage als eine Transaktion aus dem gleichen Grund eine schlechte Idee. Wenn Sie innerhalb einer expliziten Transaktion Teile von Einfügungen (etwa 100) ausführen, sollten Sie auch eine Leistungssteigerung feststellen.

Verwandte Themen