2008-08-20 5 views
63

Da sowohl ein Table Scan als auch ein Clustered Index Scan im Wesentlichen alle Datensätze in der Tabelle scannen, warum ist ein Clustered Index Scan vermutlich besser?Was ist der Unterschied zwischen einem Table Scan und einem Clustered Index Scan?

Als Beispiel - was die Performance-Unterschied zwischen dem folgenden ist, wenn es viele Datensätze ?:

declare @temp table(
    SomeColumn varchar(50) 
) 

insert into @temp 
select 'SomeVal' 

select * from @temp 

----------------------------- 

declare @temp table(
    RowID int not null identity(1,1) primary key, 
    SomeColumn varchar(50) 
) 

insert into @temp 
select 'SomeVal' 

select * from @temp 

Antwort

70

In einer Tabelle ohne Clustered-Index (eine Heap-Tabelle) sind Datenseiten nicht miteinander verknüpft. Daher erfordert das Traversieren von Seiten eine .

Eine gruppierte Tabelle hat jedoch data pages linked in a doubly linked list - sequentielle Scans werden dadurch etwas schneller. Natürlich haben Sie dafür den Aufwand, die Datenseiten in der Reihenfolge INSERT, UPDATE und DELETE in Ordnung zu halten. Eine Heap-Tabelle erfordert jedoch ein zweites Schreiben in das IAM.

Wenn Ihre Abfrage hat einen RANGE Operator (z .: SELECT * FROM TABLE WHERE Id BETWEEN 1 AND 100), dann eine Clustertabelle (in einer garantierten Ordnung ist) wäre effizienter sein - wie es die Indexseiten nutzen, um die relevanten Daten Seite (n) zu finden. Ein Heap müsste alle Zeilen scannen, da er sich nicht auf die Reihenfolge verlassen kann.

Und natürlich können Sie mit einem gruppierten Index einen CLUSTERED INDEX SEEK erstellen, der für die Performance ziemlich optimal ist ... ein Heap ohne Indizes würde immer zu einem Table Scan führen. So

:

  • Für Ihre Beispielabfrage in dem Sie alle Zeilen markieren, ist der einzige Unterschied der doppelt verknüpften Liste ein Clustered-Index unterhält. Dadurch sollte Ihre Clustered-Tabelle nur ein kleines bisschen schneller als ein Heap mit einer großen Anzahl von Zeilen sein.

  • Für eine Abfrage mit einer WHERE-Klausel, die durch den gruppierten Index (zumindest teilweise) erfüllt werden kann, werden Sie aufgrund der Reihenfolge vorausgehen - so müssen Sie nicht die gesamte Tabelle scannen.

  • Für eine Abfrage, die nicht durch den Clustered-Index erfüllt ist, sind Sie ziemlich ... sogar wieder, der einzige Unterschied ist, dass doppelt verknüpfte Liste für sequenzielles Scannen.In beiden Fällen sind Sie suboptimal.

  • Für , UPDATE und DELETE ein Heap möglicherweise oder nicht gewinnen. Der Heap muss nicht die Reihenfolge beibehalten, sondern erfordert ein zweites Schreiben an das IAM. Ich denke, der relative Leistungsunterschied wäre vernachlässigbar, aber auch ziemlich datenabhängig.

Microsoft hat ein whitepaper, die zu einem äquivalenten nicht gruppierten Index auf einem Haufen (nicht genau die gleichen wie I oben diskutiert, aber in der Nähe) einen gruppierten Index vergleicht. Ihre Schlussfolgerung besteht im Wesentlichen darin, einen gruppierten Index auf alle Tabellen zu setzen. Ich werde mein Bestes tun, um ihre Ergebnisse zusammenzufassen (auch hier beachten, dass sie wirklich einen nicht gruppierten Index zu einem gruppierten Index hier zu vergleichen - aber ich denke, es ist relativ vergleichbar):

  • INSERT Leistung: Clustered-Index gewinnt um etwa 3% aufgrund des zweiten Schreibvorgangs, der für einen Heap benötigt wird.
  • UPDATE Leistung: Clustered Index gewinnt um etwa 8% aufgrund der zweiten Suche für einen Heap benötigt.
  • DELETE Leistung: Clustered Index gewinnt um etwa 18% aufgrund der zweiten Suche benötigt und die zweite Löschung benötigt von der IAM für einen Haufen.
  • single SELECT Leistung: Clustered Index gewinnt um etwa 16% aufgrund der zweiten Suche für einen Heap benötigt.
  • Bereich SELECT Leistung: Clustered Index gewinnt um etwa 29% aufgrund der zufälligen Reihenfolge für einen Heap.
  • gleichzeitig INSERT: Heap-Tabelle gewinnt um 30% unter Last aufgrund Seitenaufteilungen für den gruppierten Index.
+1

Diese Frage kam mir heute in den Sinn. Danke @Terrapin für die Nachfrage und Danke an @Marc für die Antwort! – peakit

+1

MS Exam 70461 Abfragen von Microsoft SQL Server 2012 - Kapitel 15 Lektion 1 wird ausführlich behandelt. –

+0

Ich kann den vermeintlichen Boost, der durch diese Aussage angezeigt wird, scheinbar nicht gewinnen: "Für eine Abfrage mit einer WHERE-Klausel, die vom Clustered-Index (zumindest teilweise) erfüllt werden kann, kommst du wegen der Reihenfolge voraus - Sie müssen also nicht den gesamten Tisch scannen. " Ich habe eine Tabelle von 10 Millionen Zeilen. SELECT ID FROM Kunde WHERE Id> X wird in der gleichen Zeit ausgeführt, egal ob ich einen Clustered-Index für die ID habe oder nicht. Woher? Ich kann jedoch sehen, wie es sich vom Tabellenscan zum Clustered-Index-Scan ändert. –

-2

A-Table-Scan hat jede einzelne Zeile der Tabelle zu untersuchen. Der Clustered-Index-Scan muss nur den Index scannen. Es scannt nicht jeden Datensatz in der Tabelle. Das ist der Sinn von Indizes.

+7

-1 Das ist falsch. Die Blattebene des Clustered-Index * ist * die Tabelle. –

4

http://msdn.microsoft.com/en-us/library/aa216840(SQL.80).aspx

Der Clustered Index Scan logischer und physischer Operator scannt den Clustered-Index in der Argument-Spalte angegeben. Wenn ein optionales WHERE:() - Prädikat vorhanden ist, werden nur die Zeilen zurückgegeben, die das Prädikat erfüllen. Wenn die Argument-Spalte die ORDERED-Klausel enthält, hat der Abfrageprozessor angefordert, dass die Ausgabe der Zeilen in der Reihenfolge zurückgegeben wird, in der der gruppierte Index sie sortiert hat. Wenn die ORDERED-Klausel nicht vorhanden ist, durchsucht die Speicher-Engine den Index auf optimale Weise (ohne die zu sortierende Ausgabe zu garantieren).

http://msdn.microsoft.com/en-us/library/aa178416(SQL.80).aspx

Die Tabelle Scan logischer und physischer Operator ruft alle Zeilen aus der Tabelle in der Argument-Spalte angegeben. Wenn ein WHERE:() - Prädikat in der Spalte Argument angezeigt wird, werden nur die Zeilen zurückgegeben, die das Prädikat erfüllen.