Index Verständnisfrage

02/12/2008 - 08:02 von Andreas Schädler | Report spam
Hallo NG

SQL-SERVER 2000
Meine Abfragen auf eine grosse Tabelle sind viel zu langsam, deshalb habe
ich einen Index erstellt, gemàss folgendem Muster:
CREATE INDEX "Tabelle1_IDX1" on "Tabelle1" ("Feld1", "Feld2")
Der Index erbringt den gewünschten Erfolg für eine Abfrage, welche in SELECT
und WHERE genau diese beiden Felder anspricht. Z.B "SELECT Feld1 FROM
Tabelle1 WHERE Feld2 = @Feld2"
Wie gesagt, ich verwende aber mehrere Abfragen mit unterschiedlicher Anzahl
von Feldern. Wenn ich nun "SELECT Feld1, Feld3 FROM Tabelle1 WHERE Feld2 =
@Feld2" ausführe, wird der Index nicht mehr verwendet. Für das ist ein
weiterer Index CREATE INDEX "Tabelle1_IDX2" on "Tabelle1" ("Feld1", "Feld2",
"Feld3") nötig, so geht es wieder schnell.

Es kann doch nicht sein, dass für jede Kombination ein Index erstellt werden
muss.
Was kann ich besser machen?
Die Tabelle hat eine Spalte ID mit int identity und CONSTRAINT
"Tabelle1_PK" PRIMARY KEY ("ID").

Vielen Dank für Eure Hilfe.
Gruss
Andreas
 

Lesen sie die antworten

#1 Christoph Muthmann
02/12/2008 - 08:29 | Warnen spam
Andreas Schàdler wrote:
Hallo NG

SQL-SERVER 2000
Meine Abfragen auf eine grosse Tabelle sind viel zu langsam, deshalb
habe ich einen Index erstellt, gemàss folgendem Muster:
CREATE INDEX "Tabelle1_IDX1" on "Tabelle1" ("Feld1", "Feld2")
Der Index erbringt den gewünschten Erfolg für eine Abfrage, welche in
SELECT und WHERE genau diese beiden Felder anspricht. Z.B "SELECT
Feld1 FROM Tabelle1 WHERE Feld2 = @Feld2"
Wie gesagt, ich verwende aber mehrere Abfragen mit unterschiedlicher
Anzahl von Feldern. Wenn ich nun "SELECT Feld1, Feld3 FROM Tabelle1
WHERE Feld2 = @Feld2" ausführe, wird der Index nicht mehr verwendet.
Für das ist ein weiterer Index CREATE INDEX "Tabelle1_IDX2" on
"Tabelle1" ("Feld1", "Feld2", "Feld3") nötig, so geht es wieder
schnell.

Es kann doch nicht sein, dass für jede Kombination ein Index erstellt
werden muss.
Was kann ich besser machen?
Die Tabelle hat eine Spalte ID mit int identity und CONSTRAINT
"Tabelle1_PK" PRIMARY KEY ("ID").



Hallo Andreas,
erstelle einen Index über die Felder der Where-Bedingung, dort nimmst Du
zuerst die Felder auf, die auf Gleichheit getestet werden und danach noch
ein Feld, welches anders getestet wird. Die anderen Felder kannst Du erst
mal weglassen. Falls keine Felder mit Ungleichheit getestet wird und ein
GROUP BY verwendet wird, kannst Du auch diese Felder mit in den Index
aufnehmen. Für Joins empfiehlt sich ein Index über die Join-Felder, ggf.
ergànzt um Where und Group By Felder.

Als nàchstes gibt es dann die Möglichkeit zusàtzliche Felder mit INCLUDE
aufzunehmen. Dann brauchst Du nach dem Zugriff auf den Index nicht mehr auf
die Daten zuzugreifen. Das kann aber je nach Anwendung zu entsprechender
Last oder grosser Datenmenge führen. Manchmal ist dies aber den Aufwand
wert.

Als weiteres hast Du noch die Möglichkeit einen einzigen Index als CLUSTERED
zu definieren. Dieser sollte möglichst UNIQUE sein und für viele Abfragen
geeignet sein. In der Regel wird dies aber der Primary Key sein, was auch
einen gewissen Sinn macht.

In Deinem Fall könnte also so etwas dabei rumkommen:
CREATE INDEX Tabelle1_IDX1 on Tabelle1 (Feld2) Include (Feld1, Feld3)

Schau Dir auch mal die Vorschlàge des Datenbankmodul-Optimierungsratgebers
an. Auch wenn man diese nicht unbedingt unbesehen übernehmen sollte, da
evtl. andere Abfragen darunter leiden könnten, kann man hiervon zumindest
einiges lernen.


Einen schönen Tag noch,
Christoph
Microsoft SQL Server MVP
http://www.insidesql.org

Ähnliche fragen