2008-09-25 7 views
11

DieseIrgendwelche Auswirkungen auf die Performance in Oracle für die Verwendung von LIKE 'string' vs = 'string'?

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%'; 

ist langsamer als dieser

SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value'; 

aber was ist das?

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value'; 

Meine Tests zeigen, dass die zweiten und dritten Beispiele genau gleich sind. Wenn das stimmt, ist meine Frage, warum immer "=" verwenden?

+0

Welche Test hast du gemacht? –

+0

1 - Lief eine Anweisung gegen eine große Tabelle mit beiden Methoden viele Male, unter Berücksichtigung der Ausführungszeit 2 - Blick auf den EXPLAIN-Plan – JosephStyons

Antwort

17

Es gibt einen klaren Unterschied, wenn Sie Bind-Variablen verwenden, die Sie in Oracle für alles andere als Data Warehousing oder andere Massendatenoperationen verwenden sollten.

Nehmen wir den Fall:

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE :b1 

Oracle kann nicht wissen, dass der Wert von b1 ‚% some_value%‘ oder ‚some_value‘ usw., bis die Ausführungszeit ist, so dass es eine Abschätzung der machen Kardinalität des Ergebnisses basierend auf Heuristiken und einen geeigneten Plan, der entweder für verschiedene Werte von: b, wie "% A", "%", "A" usw. geeignet sein kann oder auch nicht

Ähnlich Probleme können mit einem Gleichheitsprädikat angewendet werden, aber der Bereich der Kardinalitäten, der sich ergeben könnte, wird viel einfacher anhand von Spaltenstatistiken oder dem Vorhandensein einer eindeutigen Integritätsbedingung geschätzt le.

Also, persönlich würde ich nicht beginnen, LIKE als Ersatz für = zu verwenden. Der Optimierer ist manchmal ziemlich einfach zu täuschen.

+0

Gute Antwort! Es erschien mir töricht, wenn ich die Frage las, aber ich konnte nicht genau sagen, warum. Dies ist die richtige Antwort. –

5

Überprüfen Sie die EXPLAIN PLAN für beide. Sie erzeugen den gleichen Ausführungsplan, also sind sie für die Datenbank dasselbe.

Sie würden = = auf Gleichheit, nicht auf Ähnlichkeit testen. Wenn Sie den Vergleichswert ebenfalls kontrollieren, macht das keinen großen Unterschied. Wenn dies von einem Benutzer gesendet wird, dann würden "Apfel" und "Apfel%" Ihnen sehr unterschiedliche Ergebnisse liefern.

+0

Bei sehr großen Tabellen kann es einen merklichen Leistungsunterschied zwischen dem LIKE-Test und = auch wenn Der Plan ist identisch. Aber es ist am besten zu testen. –

+0

Ja, wenn Sie Bind-Variable verwenden, wie Sie sollten, weiß der Optimierer nicht wirklich, was Sie an ihn übergeben werden. Es kann also nicht unbedingt für eine Wildcard auf nur einer Seite optimiert werden. (Natürlich hat Oracle diese Charakteristik vielleicht bearbeitet). –

1

Haben Sie es versucht? Testen ist der einzig sichere Weg zu wissen.

Nebenbei, keine dieser Aussagen sind sicher, die gleichen Zeilen zurückzugeben. Probieren Sie:

insert into some_table (some_field) values ('some_value'); 
insert into some_table (some_fieled) values ('1some_value2'); 
insert into some_table (some_field) values ('some1value'); 

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%'; 

SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value'; 

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value'; 

In Bezug auf die Klarheit und geringfügige Fehler zu vermeiden, ist es am besten nie LIKE zu verwenden, wenn Sie Platzhalter-Funktionalität ist es benötigen. (Offensichtlich ist es bei Ad-hoc-Abfragen wahrscheinlich in Ordnung.)

+0

Wie sehen die Unterschiede in den Ergebnissen aus? Ich habe keinen Zugriff auf einen Sandbox-Server, um Ihr Beispiel zu testen. – Luke

+0

'LIKE '% some_value%'' gibt alle drei Datensätze zurück, '= 'some_value' gibt nur den zweiten Datensatz zurück,' LIKE' some_value' gibt den ersten und dritten Datensatz zurück. –

1

LIKE '% WHATEVER%' muss einen vollständigen Index-Scan durchführen.

Wenn es nicht Prozent gibt, dann verhält es sich wie ein Gleichgestellter.

Wenn sich% auf einem Ende befindet, kann der Index ein Bereichsscan sein.

Ich bin mir nicht sicher, wie der Optimierer gebundene Felder behandelt.

3

Wenn das stimmt, ist meine Frage, warum jemals "=" verwenden?

Eine bessere Frage: Wenn das stimmt, warum "LIKE" verwenden, um auf Gleichheit zu testen? Sie erhalten Drücken der Shift-Taste zu speichern, und jeder, der das Skript liest bekommt verwechselt werden.

1

like ist formal das gleiche, wenn Sie keine Zeichen wie $% usw. haben, so ist es keine große Überraschung zu finden, dass es die gleichen Kosten hat.

Ich finde David Aldridge Antwort interessant, wie Ihre Anwendung Bind-Variablen verwenden sollte. Mit einem like '%foobar' können Sie keinen Gebrauch von der Bestellung im Index machen. Wenn die Abfrage vorkompiliert ist, führt dies zu mehr Index- oder Tabellen-Voll-Scans.

Außerdem finde ich es gefährlich, wie es zu SQL Injections und seltsame Fehler führen können (zum Beispiel, wenn ein Benutzer ein John Hacker genannt ist, kann ein Benutzer erstellen 'joh$' Namen und versuchen, sich anzumelden)

warum Das Risiko auf sich nehmen? '=' ist klarer und hat keines dieser Probleme.

Verwandte Themen