Frage

Wir haben eine Abfrage, die eine ziemlich große Tabelle wegläuft, die leider verwenden LIKE muss ‚% ABC%‘ auf ein paar varchar Felder, damit der Benutzer auf Teilnamen suchen können usw. SQL Server 2005

Möchten Sie einen Index für diese varchar den Feldern helfen jede in Bezug auf die Auswahlabfrageleistung bei der Verwendung von LIKE oder ist es im Grunde die Indizes ignorieren und einen Scan in diesen Fällen tun?

Jede andere Möglichkeiten zur Verbesserung der Leistung bei der Verwendung von LIKE?

War es hilfreich?

Lösung

Nur wenn Sie diesen Spalten die Volltextsuche hinzufügen, und verwenden Sie die Volltextabfragefunktionen von SQL Server.

Ansonsten nein, ein Index wird nicht helfen.

Andere Tipps

Sie möglicherweise durch Leistungsverbesserungen sehen Hinzufügen Index (es), es viel über die Besonderheiten abhängt:)

Wie viel von der Gesamtgröße der Reihe sind Ihre sagt Spalten? Wie viele Zeilen erwarten Sie passen? Müssen Sie alle Zeilen zurückgeben, die das Prädikat übereinstimmen oder oben nur 1 oder Top-n Zeilen?

Wenn Sie für Werte mit hohen Selektivität / Einzigartigkeit (so wenig Zeilen zurückgeben) suchen und die prädizierten Spalten sind ein eher kleiner Teil der gesamten Zeilengröße, könnte ein Index sehr nützlich sein. Es wird noch ein Scan sein, aber Ihr Index wird mehr Zeilen pro Seite als die Quelltabelle passen.

Hier ist ein Beispiel, bei dem die Gesamtzeilengröße viel größer als die Spaltengröße ist für die Suche:

create table t1 (v1 varchar(100), b1 varbinary(8000))
go
--add 10k rows of filler
insert t1 values ('abc123def', cast(replicate('a', 8000) as varbinary(8000)))
go 10000
--add 1 row to find
insert t1 values ('abc456def', cast(replicate('a', 8000) as varbinary(8000)))
go

set statistics io on 
go
select * from t1 where v1 like '%456%'
--shows 10001 logical reads

--create index that only contains the column(s) to search across
create index t1i1 on t1(v1)
go
select * from t1 where v1 like '%456%'
--or can force to 
--shows 37 logical reads

Wenn Sie bei dem tatsächlichen Ausführungsplan schauen, können Sie die Maschine sehen den Index gescannt und hat eine Lesezeichen-Suche auf der passenden Zeile. Oder Sie können dem Optimierer direkt sagen, um den Index zu verwenden, wenn es nicht diesen Plan auf seinem eigenen verwenden hatte entscheiden: select * from t1 mit (Index (t1i1)), wobei v1 like '% 456%

Wenn Sie eine Reihe von Spalten in nur wenigen zu suchen, die sehr selektiv sind, können Sie mehrere Indizes erstellen und eine Reduktion Ansatz. Z.B. zuerst eine Reihe von IDs bestimmen (oder was auch immer Ihre PK) von Ihrem hochselektiven Index, dann suchen Sie Ihre weniger selektiv Spalten mit einem Filter gegen diesen kleinen Satz von PKs.

Wenn Sie immer eine große Anzahl von Zeilen zurückgeben müssen Sie mit ziemlicher Sicherheit mit einem Tisch Scan besser dran.

So sind die möglichen Optimierungen hängen stark von den Besonderheiten Ihrer Tabellendefinition und die Selektivität Ihrer Daten.

HTH! -Adrian

Der einzige andere Weg (andere als die Verwendung von Volltext-Indexierung) Sie die Leistung verbessern könnte, ist „LIKE ABC%“ zu verwenden - fügen Sie nicht den Platzhalter an beiden Enden des Suchbegriffs - in diesem Fall könnte ein Index arbeiten.

Wenn Ihre Anforderungen sind, so dass Sie Platzhalter an beiden Enden des Suchbegriffs haben müssen, du bist kein Glück ...

Marc

Wie ‚% ABC%‘ wird immer einen vollständigen Tabellenscan durchführen. Es gibt keinen Weg dran vorbei.

Sie haben ein paar alternative Ansätze. Zur ein Volltextsuche, es ist wirklich für diese Art von Problem entwickelt, so würde ich in diesen ersten Blick.

Alternativ unter bestimmten Umständen es sinnvoll sein könnte, die Daten und Vorprozess die Zielfelder in die entsprechenden Token denormalize, fügen Sie dann diese möglichen Suchbegriffe in einem separaten zu viele Suchtabelle. So wurden zum Beispiel der Suche des Muster ‚AAA / BBB / CCC‘ und meine Nutzer auf BBB, wenn meine Daten immer aus einem Feld bestehen enthalten, dann würde ich das aus bei insert / update (und entfernen Sie auf delete) tokenize. Dies würde auch einer jener Fälle, in denen Trigger, anstatt Anwendungscode, wäre viel bevorzugt.

muss ich Betonung, dass dies nicht wirklich eine optimale Technik und sollten nur verwendet werden, wenn die Daten ein gutes Spiel für den Ansatz ist, und aus irgendeinem Grund Sie nicht wollen, Volltextsuche (und die Datenbank-Performance auf dergleichen verwenden scannen ist wirklich nicht akzeptabel). Es ist auch wahrscheinlich Wartung Kopfschmerzen weiter auf der ganzen Linie zu erzeugen.

erstellen Statistiken über diese Spalte. SQL Server 2005 hat sich die in String-Suche optimiert, so dass Sie davon profitieren könnten.

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