Frage

Ich versuche, die Leistung einer Abfrage zu verbessern, die sehr langsam läuft. Nach dem Durchgang der Tatsächlicher Ausführungsplan; Ich fand das a Clustered Indexsuch nahm 82%auf. Gibt es eine Möglichkeit für mich, die Leistung auf einem zu verbessern Index suchen? Unten ist ein Bild des Problems Index suchen Aus dem Ausführungsplan sowie dem Index und der Tabelle, die es verwendet.

ALT Text http://img340.imageshack.us/img340/1346/seek.png

Index:

/****** Object:  Index [IX_Stu]    Script Date: 12/28/2009 11:11:43 ******/
CREATE CLUSTERED INDEX [IX_Stu] ON [dbo].[stu] 
(
 [StuKey] ASC
)WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]

Tabelle (einige Spalten für Kürze weggelassen):

CREATE TABLE [dbo].[stu](
 [StuCertKey] [int] IDENTITY(1,1) NOT NULL,
 [StuKey] [int] NULL
 CONSTRAINT [PK_Stu] PRIMARY KEY NONCLUSTERED 
(
 [StuCertKey] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
War es hilfreich?

Lösung

Ich verallgemeinere hier, aber ...

Ein Clustered Index-Such ist größtenteils das Best-Case-Szenario. Die einzige Möglichkeit, wie ich mir vorstellen kann, um die Leistung zu verbessern, wäre:

  • Aktualisieren Sie die Abfrage, um nach Möglichkeit weniger Zeilen/Spalten zurückzugeben.
  • Defragment oder Wiederaufbau des Index;
  • Partitionieren Sie den Index über mehrere Datenträger/Server hinweg.

Wenn es nur 138 Zeilen zurückgibt und es so langsam ist ... vielleicht wird es von einem anderen Prozess blockiert? Testen Sie dies isoliert oder sind andere Benutzer/Prozesse gleichzeitig online? Oder vielleicht ist es sogar ein Hardwareproblem, wie ein Scheibenfehler.

Andere Tipps

Der Clustered-Index sucht auf, wenn nicht geklusterte Indizes verwendet werden und nicht unbedingt schlecht sind.

Betrachten Sie die folgende Frage:

SELECT s.StuKey, s.Name, s.Address, s.City, s.State FROM stu s WHERE State='TX'

Wenn es nur einen Cluster -Index für Stukey gibt, hat SQL Server nur 1 Option. Er muss die gesamte Tabelle scannen, um nach Zeilen zu suchen, wobei State = "Tx 'diese Zeilen zurückgibt.

Wenn Sie einen nicht geklüsterten Index zum Status hinzufügen

CREATE INDEX IX_Stu_State on Stu (State)

Jetzt hat SQL Server eine neue Option. Es kann wählen, ob es den nicht geklusterten Index verwenden kann, der die Zeilen erzeugt, wobei state = 'tx'. Um jedoch die verbleibenden Spalten in die Auswahl zurückzugeben, muss sie diese Spalten nach einer Clustered -Index suchen, die für jede Zeile sucht.

Wenn Sie den Clustered -Index sucht, können Sie Ihren Index "abdecken", indem Sie zusätzliche Spalten in ihn einbeziehen.

 CREATE INDEX IX_Stu_State2 on Stu (State) INCLUDE (name, address, city )

Dieser Index enthält nun alle Spalten, die zur Beantwortung der obigen Abfrage erforderlich sind. In der Abfrage wird ein Index durchgeführt, um nur die Zeilen zurückzugeben, an denen State = 'TX', und die zusätzlichen Spalten aus dem nicht geklusterten Index herausgezogen werden können, sodass der Cluster-Index nachgibt.

Ein Clustered Index -Bereich sucht nach, die 138 Zeilen zurückgeben, nicht Ihr Problem.

Technisch gesehen können Sie die Suchleistung verbessern, indem Sie den Clustered -Index schmaler machen:

Beide können einen ziemlich dramatischen Einfluss auf die Range -Suchzeit haben, da sie den IO reduzieren und die Notwendigkeit, physische Lesevorgänge zu treffen, zu erreichen. Natürlich variiert das Ergebnis wie normalerweise eine große Anzahl anderer Faktoren, z. Als Randnotiz hat die Fragmentierung normalerweise nur einen marginalen Einfluss auf einen so kurzen Reichweite -Scan. Wieder kommt es an.

Aber wie gesagt, ich bezweifle sehr, dass dies Ihr wahres Problem ist. Sie haben nur ausgewählte Teile des Plans und die Ergebnisse Ihrer eigenen Analyse veröffentlicht. Die wahre Grundursache kann anderswo vollständig liegen.

Gedanken...

  • Warum wird ix_stu geclustert? Innen fügt SQL Server nicht eindeutigen Cluster-Indizes ein 4-Byte-"-Diplyifier" hinzu. Was ist die Rechtfertigung? Dies bläht auch auch Ihre PK

  • Was ist die eigentliche Abfrage, die Sie ausführen?

  • Warum schließlich 80%FILFACTOR?

Bearbeiten:

  • Ein "normaler" Füllfaktor wäre 90%, aber dies ist nur eine Faustregel

  • Eine 11 -BE -Anfrage? Das ist höchstwahrscheinlich Ihr Problem. Was sind deine Verbindung, wo Klauseln usw.? Was ist der vollständige Textplan?

Einige allgemeine Ratschläge: Wenn ich eine Abfragemoptimierung durchführen muss, schreibe ich zunächst das aus, was der Ausführungsplan sein sollte.

Sobald ich entschieden habe, was ich denke, der Ausführungsplan sollte, versuche ich, die eigentliche Abfrage zu diesem Plan anzupassen. Die Techniken, um dies zu tun, sind für jedes DBMS unterschiedlich und wechseln nicht unbedingt von einem zum anderen oder manchmal zwischen verschiedenen Versionen des DBM.

Beachten Sie, dass die DBMs jeweils nur eine Verbindung ausführen können: Es beginnt mit zwei Anfangstabellen, verbindet diese und nimmt dann das Ergebnis dieser Operation und verbindet sie an den nächsten Tisch. Das Ziel bei jedem Schritt ist es, die Anzahl der Zeilen im Zwischenergebnissatz zu minimieren (korrekter, um die Anzahl der Blöcke zu minimieren, die gelesen werden müssen, um die Zwischenergebnisse zu erzielen, dies bedeutet jedoch im Allgemeinen wenigste Zeilen).

Haben Sie einige Wartung in diesem Index ausprobiert? Wie es defragert? Es scheint wirklich seltsam, dass es so viel kostet (120.381). Indexsuch ist die schnellste Indexoperation, sollte nicht so lange dauern. Können Sie die Abfrage posten?

Was passiert, wenn Sie Ihre fest codieren? WO Kriterien wie diese:

SELECT StuCertKey, StuKey FROM stu 
WHERE stuKey in (/* list 50 values of StuKey here */)

Wenn es immer noch sehr langsam ist, haben Sie ein internes Problem. Wenn es schneller ist, dann ist der Index nicht Ihr Engpass, sondern der ist der Schließt sich an Dass du das tust, um das zu erstellen WO Filter.

Beachten Sie, dass SELECT * Kann sehr langsam sein, wenn es viele große Säulen gibt, und besonders wenn es Blobs gibt.

Überprüfen Sie die Indexstatike.

Die Neuberechnung der Cluster-Index-Statistik wird das Problem lösen.

In meinem Fall suchte ich nach 30 Rekorde in 40 m recored. Der Ausführungsplan besagt, dass er den Cluster-Index durchläuft, aber ungefähr 200 ms dauerte. Und der Index wurde nicht defragmentiert. Nach dem Neuberechnen der Statistiken wird es unter 10 ms erledigt!

Den Index wieder aufbauen und Statistiken berechnen?

Der einzige andere Weg, den ich mir vorstellen kann, um es zu beschleunigen, besteht darin, die Tabelle zu partitionieren, die möglicherweise möglich ist oder nicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top