LIKE vs CONTAINS auf SQL Server


209

Welche der folgenden Abfragen ist schneller (LIKE vs CONTAINS)?

SELECT * FROM table WHERE Column LIKE '%test%';

oder

SELECT * FROM table WHERE Contains(Column, "test");

12
Akzeptieren Sie eine Antwort, oder?
AgentFire

7
Er war seit Jahren nicht mehr auf Mann.
Chris

Antworten:


174

Die zweite (vorausgesetzt, Sie meinen CONTAINS, und tatsächlich in eine gültige Abfrage einfügen) sollte schneller sein, da sie eine Art Index verwenden kann (in diesem Fall einen Volltextindex). Diese Form der Abfrage ist natürlich nur verfügbar, wenn sich die Spalte in einem Volltextindex befindet. Ist dies nicht der Fall, ist nur das erste Formular verfügbar.

Die erste Abfrage, die LIKE verwendet, kann keinen Index verwenden, da sie mit einem Platzhalter beginnt und daher immer einen vollständigen Tabellenscan erfordert.


Die CONTAINSAbfrage sollte lauten:

SELECT * FROM table WHERE CONTAINS(Column, 'test');

@edze - du meinst, die gleiche Seite, die bereits verlinkt ist, ist meine erste Erwähnung CONTAINS? Was davon? Die ursprüngliche Form der Frage hatte, Column CONTAIN("%test%",Column)>0die nirgends annähernd gültig war. Es ist immer noch nicht ganz richtig.
Damien_The_Unbeliever

Dies hat uns geholfen, eine Abfrage in SharePoint zu sortieren. Haben Sie ein anderes großes Antwortabzeichen.
Ouflak

14

Nachdem ich beide Abfragen auf einer SQL Server 2012-Instanz ausgeführt habe, kann ich bestätigen, dass die erste Abfrage in meinem Fall am schnellsten war.

Die Abfrage mit dem LIKESchlüsselwort zeigte einen Clustered-Index-Scan.

Das CONTAINShatte auch einen Clustered-Index-Scan mit zusätzlichen Operatoren für die Volltextübereinstimmung und einen Merge-Join.

Planen


8
Die gruppierten Indexblattseiten sind die Tabelle. Eine LIKEAbfrage mit einem führenden Platzhalter kann den Indexteil nicht effizient verwenden. Es muss nur das Ganze gescannt werden. Obwohl es zweifellos einige Umstände gibt, unter denen der vollständige CI-Scan eine bessere Leistung erbringt als eine Abfrage unter Verwendung des Volltextindex (möglicherweise, wenn beispielsweise ein sehr hoher Anteil der Zeilen übereinstimmt), ist dies größtenteils die Ausnahme, die Sie nicht bestätigen können ".
Martin Smith

Nun, ich schaue mir einen tatsächlichen Ausführungsplan an, der über 200.000 Datensätze abruft. Wenn beide Abfragen in einem Stapel zusammengefasst wurden, haben beide den Clustered-Index gescannt. Zusätzlich verursacht die Abfrage "CONTAINS" zusätzliche Kosten für FULL TEXT MATCH und einen MERGE JOIN.
MI C

Wenn ein Zusammenführungs-Join ausgewählt wird, schätzt SQL Server, dass mehr als x% der Zeilen mit dem Prädikat übereinstimmen. (Wobei X = der Wendepunkt ist ). In diesem Fall würde ich mir vorstellen, dass beide ziemlich gleichmäßig zusammenpassen könnten. Die im Ausführungsplan angegebenen Kosten sind nur Schätzungen (auch im tatsächlichen Plan). Der FT-Plan enthält zwar zusätzliche Betreiber von Ausführungsplänen, bietet jedoch einige Vorteile. Der Merge-Join kann vor dem Ende des Scans angehalten werden, wenn die FT-Ergebnisse ausgehen und er auch nicht ausgewertet werden muss LIKE.
Martin Smith

1
Ich habe eine ähnliche Abfrage ausgeführt, um den Ausführungsplan in SQL 2012 zu überprüfen, und es gab mir eine Indexsuche. Vielleicht war der Tisch im Beispiel hier fast leer. In einigen Fällen verwendet SQL stattdessen einen Index-Scan in einer sehr kleinen Tabelle, um den Index zu verwenden, da dieser schneller ist.
Juan

8

Ich denke, CONTAINSdas hat länger gedauert und verwendet, Mergeweil Sie einen Bindestrich ("-") in Ihrer Abfrage hatten adventure-works.com.

Der Bindestrich ist ein Unterbrechungswort, daher wurde im CONTAINSVolltextindex adventurenach works.comden Ergebnissen gesucht und danach gesucht und die Ergebnisse zusammengeführt.


8

Versuchen Sie auch, dies zu ändern:

    SELECT * FROM table WHERE Contains(Column, "test") > 0;

Dazu:

    SELECT * FROM table WHERE Contains(Column, '"*test*"') > 0;

Ersteres findet Datensätze mit Werten wie " Dies ist ein Test " und " Ein Testfall ist der Plan ".

Letztere finden auch Datensätze mit Werten wie " Ich teste dies " und " Dies ist das Größte ".


4
Funktioniert das Setzen des Sterns vor und nach dem Suchbegriff? Beim Lesen der Dokumentation für CONTAINSwerden nur Präfixbegriffe wie "test *", keine Suffixbegriffe wie " test" und keine vollständige Teilstringsuche wie "* test " erwähnt. Ich habe es jedoch nicht versucht.
Matt Forsythe

4
Wenn Sie die Dokumentation zu CONTAINS ( docs.microsoft.com/en-us/sql/t-sql/queries/… ) lesen , wird nur die Suche nach Präfixen unterstützt. Ich habe dies mehrfach experimentell versucht und es ist nicht möglich, "Dies ist das Größte" (in SQL Server) mit Contains (Spalte, " Test ") zu finden
cl0rkster
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.