Frage

Nehmen wir an, ich habe eine Tabelle mit dem Namen „Kategorie“ in einer SQL Server 2005-Datenbank.Die Kategorie hat die Kategorie_ID (bigint, Identity) als Primärschlüssel und Namen (nvarchar(50)).Offensichtlich gibt es einen Clustered-Index für „category_id“, und ich habe auch einen Nicht-Clustered-Index für „Name“ hinzugefügt.Wenn ich die Abfrage ausführe

SELECT * 
FROM Category 
WHERE [name] like '%zz%'

und schauen Sie sich den Ausführungsplan über Management Studio 2005 an. Dort steht, dass ein Clustered-Index-Scan verwendet wird.Der Clustered-Index bezieht sich auf die Kategorie-ID, nicht auf den Namen.

Warum steht da so etwas?

War es hilfreich?

Lösung

Das "Like '%Zzz%" "negiert den möglichen Nutzen des Index weitgehend, da er jeden Eintrag untersuchen muss, um festzustellen, ob er übereinstimmt. Das Durchführen des "Select *" bedeutet, dass es sich um den Clustered -Index handelt, um alle Spaltendaten auf die übereinstimmenden Datensätze zu erhalten. Der Optimierer kann nicht schätzen, wie viele Übereinstimmungen es dort geben wird, wählt den Cluster -Index aus.

Versuchen Sie, es in "Like" Zz%"zu ändern und zu sehen, was Sie bekommen.

Andere Tipps

Denn in Ihrem Beispiel ist [category_id] die PK (Identität) und solche PKs verfügen standardmäßig über einen zugehörigen Clustered-Index (in MS-SQL können Sie nur einen Clustered-Index haben).

Da Sie außerdem nicht erwähnen, dass [Name] einen Index hat, steht in SQL tatsächlich nur der PK für einen Scan zur Verfügung (und betrachtet daher jede Zeile zu 100 % Kosten).

Übrigens:Hier ist ein interessanter Artikel über Indizes und LIKE: http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx )

BEARBEITEN – Ein Ausschnitt des obigen Links hinzugefügt, der den Artikel zusammenfasst, da Links veraltet sein können:

Autor:Nummer 2 (John Nelson)

...die Regeln für die Indexnutzung mit LIKE lauten im Großen und Ganzen wie folgt:

1) Wenn Ihr Filterkriterium gleich = verwendet und das Feld indiziert ist, wird höchstwahrscheinlich eine INDEX/CLUSTERED INDEX SEEK verwendet

2) Wenn Ihr Filterkriterium LIKE verwendet, ohne Platzhalter (z. B. wenn Sie einen Parameter in einem Webbericht hätten, der ein % haben KÖNNTE, Sie aber stattdessen die vollständige Zeichenfolge verwenden), ist es ungefähr so ​​wahrscheinlich wie Nr. 1, den Index zu verwenden.Die erhöhten Kosten sind fast nichts.

3) Wenn Ihr Filterkriterium LIKE verwendet, aber mit einem Platzhalter am Anfang (wie in Name0 LIKE '%UTER'), ist die Wahrscheinlichkeit, dass der Index verwendet wird, viel geringer, es kann aber dennoch zumindest ein INDEX-SCAN ganz oder teilweise durchgeführt werden Bereich des Indexes.

4) Wenn Ihre Filterkriterien jedoch LIKE verwenden, aber mit einem STRING FIRST beginnen und irgendwo DANACH Platzhalter haben (wie in Name0 LIKE 'COMP%ER'), dann verwendet SQL möglicherweise einfach eine INDEX-Suche, um schnell Zeilen zu finden, die das haben Geben Sie zunächst dieselben Startzeichen ein und durchsuchen Sie dann diese Zeilen nach einer genauen Übereinstimmung.

Hinweis:(Bedenken Sie auch, dass die SQL-Engine einen Index möglicherweise immer noch nicht wie erwartet verwendet, je nachdem, was sonst noch in Ihrer Abfrage vor sich geht und mit welchen Tabellen Sie verknüpfen.Die SQL-Engine behält sich das Recht vor, Ihre Abfrage ein wenig umzuschreiben, um die Daten auf eine Art und Weise zu erhalten, die ihrer Meinung nach am effizientesten ist. Dazu kann ein INDEX-SCAN anstelle einer INDEX-Suche gehören.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top