webentwicklung-frage-antwort-db.com.de

Entspricht (=) vs. LIKE

Gibt es bei der Verwendung von SQL irgendwelche Vorteile bei der Verwendung von = in einer WHERE -Klausel anstelle von LIKE?

Ohne spezielle Operatoren können LIKE und = sind gleich, oder?

266
Travis

Verschiedene Operatoren

LIKE und = sind verschiedene Operatoren. Die meisten Antworten konzentrieren sich hier auf die Platzhalterunterstützung, was nicht der einzige Unterschied zwischen diesen Operatoren ist!

= Ist ein Vergleichsoperator, der mit Zahlen und Zeichenfolgen arbeitet. Beim Vergleichen von Zeichenfolgen vergleicht der Vergleichsoperator ganze Zeichenfolgen.

LIKE ist ein String-Operator, der zeichenweise vergleicht.

Um die Sache zu verkomplizieren, verwenden beide Operatoren ein Kollation , das wichtige Auswirkungen auf das Ergebnis des Vergleichs haben kann.

Motivierendes Beispiel

Lassen Sie uns zunächst ein Beispiel identifizieren, in dem diese Operatoren offensichtlich unterschiedliche Ergebnisse liefern. Gestatten Sie mir, aus dem MySQL-Handbuch zu zitieren:

Gemäß dem SQL-Standard führt LIKE einen Abgleich pro Zeichen durch und kann daher andere Ergebnisse als der Vergleichsoperator = liefern:

mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
|                                    1 |
+--------------------------------------+

Bitte beachten Sie, dass diese Seite des MySQL-Handbuchs String-Vergleichsfunktionen heißt und = Nicht behandelt wird, was impliziert, dass = Kein reiner String-Vergleich ist Funktion.

Wie funktioniert =?

Das SQL Standard § 8.2 beschreibt, wie = Strings vergleicht:

Der Vergleich zweier Zeichenketten wird wie folgt ermittelt:

a) Wenn die Länge in Zeichen von X nicht der Länge in Zeichen von Y entspricht, wird die kürzere Zeichenfolge zu Vergleichszwecken durch eine Kopie von sich selbst ersetzt, die auf die Länge der längeren Zeichenfolge erweitert wurde durch Verkettung rechts von einem oder mehreren Pad-Zeichen, wobei das Pad-Zeichen basierend auf CS ausgewählt wird. Wenn CS das NO PAD-Attribut hat, ist das Pad-Zeichen ein implementierungsabhängiges Zeichen, das sich von allen Zeichen im Zeichensatz von X und Y unterscheidet und weniger als jede Zeichenfolge unter CS sortiert. Ansonsten ist das Pad-Zeichen a.

b) Das Ergebnis des Vergleichs von X und Y ergibt sich aus der Sortierfolge CS.

c) Abhängig von der Sortierfolge können zwei Zeichenfolgen als gleich verglichen werden, auch wenn sie unterschiedlich lang sind oder unterschiedliche Zeichenfolgen enthalten. Wenn die Operationen MAX, MIN, DISTINCT, Verweise auf eine Gruppierungsspalte und die Operatoren UNION, EXCEPT und INTERSECT auf Zeichenfolgen verweisen, ist der von diesen Operationen aus einer Menge solcher gleicher Werte ausgewählte spezifische Wert von der Implementierung abhängig.

(Betonung hinzugefügt.)

Was bedeutet das? Dies bedeutet, dass der Operator = Beim Vergleichen von Zeichenfolgen nur eine dünne Hülle um die aktuelle Kollatierung ist. Eine Kollatierung ist eine Bibliothek, die verschiedene Regeln zum Vergleichen von Zeichenfolgen enthält. Hier ist ein Beispiel für eine binäre Kollatierung von MySQL :

static int my_strnncoll_binary(const CHARSET_INFO *cs __attribute__((unused)),
                               const uchar *s, size_t slen,
                               const uchar *t, size_t tlen,
                               my_bool t_is_prefix)
{
  size_t len= MY_MIN(slen,tlen);
  int cmp= memcmp(s,t,len);
  return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
}

Diese bestimmte Sortierung vergleicht Byte für Byte (weshalb sie "binär" heißt - Zeichenfolgen wird keine besondere Bedeutung beigemessen). Andere Kollatierungen bieten möglicherweise erweiterte Vergleiche.

Hier ist zum Beispiel ein TF-8-Kollatierung , das Vergleiche ohne Berücksichtigung der Groß- und Kleinschreibung unterstützt. Der Code ist zu lang, um ihn hier einzufügen, aber gehen Sie zu diesem Link und lesen Sie den Text von my_strnncollsp_utf8mb4(). Diese Sortierung kann mehrere Bytes gleichzeitig verarbeiten und verschiedene Transformationen anwenden (z. B. Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung). Der Operator = Ist vollständig von den Unklarheiten der Kollation abstrahiert.

Wie funktioniert LIKE?

Das SQL Standard § 8.5 beschreibt, wie LIKE Zeichenketten vergleicht:

Das <Prädikat>

M LIKE P

ist wahr, wenn es eine Aufteilung von M in Teilzeichenfolgen gibt, so dass:

i) Eine Teilzeichenfolge von M ist eine Folge von 0 oder mehr zusammenhängenden <Zeichendarstellungen> von M und jede <Zeichendarstellung> von M ist Teil genau einer Teilzeichenfolge.

ii) Wenn der i-te Teilstringspezifizierer von P ein beliebiger Zeichenspezifizierer ist, ist der i-te Teilstring von M eine beliebige einzelne <Zeichendarstellung>.

iii) Wenn der i-te Teilstringspezifizierer von P ein beliebiger Stringspezifizierer ist, dann ist der i-te Teilstring von M eine beliebige Folge von 0 oder mehr <Zeichendarstellung> s.

iv) Wenn der i-te Teilstringspezifizierer von P weder ein beliebiger Zeichenspezifizierer noch ein beliebiger Stringspezifizierer ist, dann ist der i-te Teilstring von M gemäß der Sortierung gleich diesem Teilstringspezifizierer Sequenz des <like-Prädikats>, ohne das Anhängen von <Leerzeichen> an M, und hat die gleiche Länge wie dieser Teilstringspezifizierer.

v) Die Anzahl der Teilstrings von M ist gleich der Anzahl der Teilstringspezifizierer von P.

(Betonung hinzugefügt.)

Das ist ziemlich wortreich, also lasst es uns zusammenfassen. Die Punkte ii und iii beziehen sich jeweils auf die Platzhalter _ Und %. Wenn P keine Platzhalter enthält, gilt nur Punkt iv. Dies ist der Fall, wenn das OP Interesse zeigt.

In diesem Fall vergleicht es jede "Teilzeichenfolge" (einzelne Zeichen) in M mit jeder Teilzeichenfolge in P unter Verwendung der aktuellen Kollatierung.

Schlussfolgerungen

Im Endeffekt vergleicht = Beim Vergleichen von Zeichenfolgen die gesamte Zeichenfolge, während LIKE jeweils ein Zeichen vergleicht. Beide Vergleiche verwenden die aktuelle Kollatierung. Dieser Unterschied führt in einigen Fällen zu unterschiedlichen Ergebnissen, wie das erste Beispiel in diesem Beitrag zeigt.

Welches solltest du verwenden? Niemand kann Ihnen das sagen - Sie müssen dasjenige verwenden, das für Ihren Anwendungsfall richtig ist. Optimieren Sie nicht vorzeitig, indem Sie die Vergleichsoperatoren wechseln.

241
Mark E. Haase

Der Gleichheitsoperator (=) ist ein "Vergleichsoperator vergleicht zwei Werte auf Gleichheit". Mit anderen Worten, in einer SQL-Anweisung wird nur dann true zurückgegeben, wenn beide Seiten der Gleichung gleich sind. Zum Beispiel:

SELECT * FROM Store WHERE Quantity = 200;

Der LIKE-Operator "implementiert einen Mustervergleich", der versucht, "einen Zeichenfolgenwert mit einer Musterzeichenfolge abzugleichen, die Platzhalterzeichen enthält". Zum Beispiel:

SELECT * FROM Employees WHERE Name LIKE 'Chris%';

LIKE wird im Allgemeinen nur mit Strings verwendet und ist (glaube ich) schneller. Der Gleichheitsoperator behandelt Platzhalterzeichen als Literalzeichen. Die Differenz der zurückgegebenen Ergebnisse ist wie folgt:

SELECT * FROM Employees WHERE Name = 'Chris';

Und

SELECT * FROM Employees WHERE Name LIKE 'Chris';

Gibt das gleiche Ergebnis zurück, obwohl die Verwendung von LIKE im Allgemeinen länger dauert, da es eine Musterübereinstimmung gibt. Jedoch,

SELECT * FROM Employees WHERE Name = 'Chris%';

Und

SELECT * FROM Employees WHERE Name LIKE 'Chris%';

Würde unterschiedliche Ergebnisse zurückgeben, wobei die Verwendung von "=" nur zu Ergebnissen führt, bei denen "Chris%" zurückgegeben wird und der LIKE-Operator alles zurückgibt, was mit "Chris" beginnt.

Ich hoffe, das hilft. Einige gute Informationen finden Sie hier .

167
achinda99

LIKE und = sind anders. LIKE ist das, was Sie in einer Suchabfrage verwenden würden. Es erlaubt auch Platzhalter wie _ (einfacher Zeichenplatzhalter) und % (Platzhalter für mehrere Zeichen).

= sollte verwendet werden, wenn Sie genaue Übereinstimmungen wünschen, und es wird schneller sein.

Diese Seite erklärt LIKE

16
WalterJ89

Dies ist ein Kopieren/Einfügen einer anderen meiner Antworten auf die Frage SQL 'like' vs '=' performance :

Ein persönliches Beispiel mit MySQL 5.5: Ich hatte eine innere Verknüpfung zwischen zwei Tabellen, einer von drei Millionen Zeilen und einer von zehntausend Zeilen.

Bei Verwendung eines Like-Werts für einen Index wie folgt (keine Platzhalter) dauerte es ungefähr 30 Sekunden:

where login like '12345678'

mit "EXPLAIN" bekomme ich:

enter image description here

Bei Verwendung eines '=' für dieselbe Abfrage dauerte es ungefähr 0,1 Sekunden:

where login ='12345678'

Mit "EXPLAIN" bekomme ich:

enter image description here

Wie Sie sehen, hat like die Indexsuche vollständig abgebrochen, sodass die Abfrage 300-mal länger gedauert hat.

15
Aris

Ein Unterschied - abgesehen von der Möglichkeit, Platzhalter mit LIKE zu verwenden - besteht in nachgestellten Leerzeichen: Der Operator = ignoriert nachgestellte Leerzeichen, LIKE jedoch nicht.

11
ISW

Hängt vom Datenbanksystem ab.

Im Allgemeinen ohne Sonderzeichen sind yes, = und LIKE gleich.

Einige Datenbanksysteme können jedoch Sortierungseinstellungen bei den verschiedenen Operatoren unterschiedlich behandeln.

Beispielsweise wird bei MySQL-Vergleichen mit = on-Zeichenfolgen standardmäßig immer zwischen Groß- und Kleinschreibung unterschieden, sodass LIKE ohne Sonderzeichen identisch ist. Bei einigen anderen RDBMS wird bei LIKE die Groß- und Kleinschreibung nicht berücksichtigt, bei = hingegen nicht.

10
ʞɔıu

In diesem Beispiel wird davon ausgegangen, dass varcharcol kein '' Enthält und keine leere Zelle für diese Spalte enthält

select * from some_table where varcharCol = ''
select * from some_table where varcharCol like ''

Die erste führt zu einer Ausgabe von 0 Zeilen, während die zweite die gesamte Liste anzeigt. = ist ein strikt passender Fall, während like wie ein Filter wirkt. Hat der Filter keine Kriterien, sind alle Daten gültig.

like - arbeitet aufgrund seines Zwecks etwas langsamer und ist für die Verwendung mit varchar und ähnlichen Daten vorgesehen.

9
Arnab

Die Verwendung von = vermeidet Konflikte mit Platzhaltern und Sonderzeichen in der Zeichenfolge, wenn Sie die Abfrage zur Laufzeit erstellen.

Dies erleichtert dem Programmierer das Leben, da er nicht alle speziellen Platzhalterzeichen, die möglicherweise in der LIKE-Klausel vorkommen, entziehen muss und nicht das beabsichtigte Ergebnis erzielt. Immerhin ist = das 99% Use-Case-Szenario, es wäre ein Schmerz, jedes Mal entkommen zu müssen.

rollt mit den Augen in den 90ern

Ich vermute auch, dass es etwas langsamer ist, aber ich bezweifle, dass es wichtig ist, wenn das Muster keine Platzhalter enthält.

6
Coincoin

Wenn Sie nach einer genauen Übereinstimmung suchen, können Sie sowohl, = als auch LIKE verwenden.

Die Verwendung von "=" ist in diesem Fall etwas schneller (Suche nach einer genauen Übereinstimmung) - Sie können dies selbst überprüfen, indem Sie dieselbe Abfrage zweimal in SQL Server Management Studio verwenden, einmal "=", einmal "LIKE" und einmal "LIKE" dann mit der "Abfrage"/"Aktuellen Ausführungsplan einbeziehen".

Führen Sie die beiden Abfragen aus, und Sie sollten Ihre Ergebnisse sowie die beiden tatsächlichen Ausführungspläne zweimal sehen. In meinem Fall wurden sie zu 50% gegen 50% aufgeteilt, aber der Ausführungsplan "=" hat geringere "geschätzte Teilbaumkosten" (angezeigt, wenn Sie den Mauszeiger über das am weitesten links stehende "SELECT" -Feld halten) - aber es ist wirklich so kein großer Unterschied.

Wenn Sie jedoch mit Platzhaltern in Ihrem LIKE-Ausdruck suchen, nimmt die Suchleistung ab. Die Suche "LIKE Mill%" kann immer noch recht schnell sein - SQL Server kann einen Index für diese Spalte verwenden, falls vorhanden. Die Suche nach "LIKE% expression%" ist schrecklich langsam, da SQL Server diese Suche nur durch einen vollständigen Tabellenscan durchführen kann. Also sei vorsichtig mit deinen LIKE's!

Marc

6
marc_s

Um die ursprüngliche Frage nach der Leistung zu beantworten, kommt es auf Indexauslastung an. Bei einem einfachen Tabellenscan sind "LIKE" und "=" identisch. Wenn es sich um Indizes handelt, ist abhängig davon, wie die LIKE-Klausel gebildet wird. Wo befinden sich die Platzhalter?


Folgendes berücksichtigen:

CREATE TABLE test(
    txt_col  varchar(10) NOT NULL
)
go

insert test (txt_col)
select CONVERT(varchar(10), row_number() over (order by (select 1))) r
  from master..spt_values a, master..spt_values b
go

CREATE INDEX IX_test_data 
    ON test (txt_col);
go 

--Turn on Show Execution Plan
set statistics io on

--A LIKE Clause with a wildcard at the beginning
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '%10000'
--Results in
--Table 'test'. Scan count 3, logical reads 15404, physical reads 2, read-ahead reads 15416, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index SCAN is 85% of Query Cost

--A LIKE Clause with a wildcard in the middle
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '1%99'
--Results in
--Table 'test'. Scan count 1, logical reads 3023, physical reads 3, read-ahead reads 3018, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost for test data, but it may result in a Table Scan depending on table size/structure

--A LIKE Clause with no wildcards
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col like '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO

--an "=" clause = does Index Seek same as above
DBCC DROPCLEANBUFFERS
SELECT txt_Col from test where txt_col = '10000'
--Results in
--Table 'test'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
--Index Seek is 100% of Query Cost
GO


DROP TABLE test

Bei Verwendung von "=" und "LIKE" kann es auch zu vernachlässigbaren Unterschieden bei der Erstellung des Abfrageplans kommen.

6
Laramie

Neben den Platzhaltern hängt der Unterschied zwischen = UND LIKE sowohl vom Typ des SQL-Servers als auch vom Spaltentyp ab.

Nehmen Sie dieses Beispiel:

CREATE TABLE testtable (
  varchar_name VARCHAR(10),
  char_name CHAR(10),
  val INTEGER
);

INSERT INTO testtable(varchar_name, char_name, val)
    VALUES ('A', 'A', 10), ('B', 'B', 20);

SELECT 'VarChar Eq Without Space', val FROM testtable WHERE varchar_name='A'
UNION ALL
SELECT 'VarChar Eq With Space', val FROM testtable WHERE varchar_name='A '
UNION ALL
SELECT 'VarChar Like Without Space', val FROM testtable WHERE varchar_name LIKE 'A'
UNION ALL
SELECT 'VarChar Like Space', val FROM testtable WHERE varchar_name LIKE 'A '
UNION ALL
SELECT 'Char Eq Without Space', val FROM testtable WHERE char_name='A'
UNION ALL
SELECT 'Char Eq With Space', val FROM testtable WHERE char_name='A '
UNION ALL
SELECT 'Char Like Without Space', val FROM testtable WHERE char_name LIKE 'A'
UNION ALL
SELECT 'Char Like With Space', val FROM testtable WHERE char_name LIKE 'A '
  • Mit MS SQL Server 2012 werden die nachgestellten Leerzeichen im Vergleich ignoriert, außer mit LIKE, wenn der Spaltentyp VARCHAR ist.

  • Mit MySQL 5.5 werden die nachgestellten Leerzeichen für = Ignoriert, nicht jedoch für LIKE, beide mit CHAR und VARCHAR .

  • Mit PostgreSQL 9.1 sind Leerzeichen sowohl bei = Als auch bei LIKE mit VARCHAR von Bedeutung, jedoch nicht bei CHAR (siehe - Dokumentation ).

    Das Verhalten mit LIKE unterscheidet sich auch mit CHAR.

    Verwenden Sie die gleichen Daten wie oben und verwenden Sie ein explizites CAST für den Spaltennamen macht auch einen Unterschied :

    SELECT 'CAST none', val FROM testtable WHERE char_name LIKE 'A'
    UNION ALL
    SELECT 'CAST both', val FROM testtable WHERE
        CAST(char_name AS CHAR) LIKE CAST('A' AS CHAR)
    UNION ALL
    SELECT 'CAST col', val FROM testtable WHERE CAST(char_name AS CHAR) LIKE 'A'
    UNION ALL
    SELECT 'CAST value', val FROM testtable WHERE char_name LIKE CAST('A' AS CHAR)
    

    Dies gibt nur Zeilen für "CAST both" und "CAST col" zurück.

4
Bruno

Das LIKE-Schlüsselwort ist zweifellos mit einem "Leistungspreis" versehen. Das heißt, wenn Sie ein Eingabefeld haben, das möglicherweise Platzhalterzeichen enthält, die in Ihrer Abfrage verwendet werden können, würde ich die Verwendung von LIKE nur wenn empfehlen. Die Eingabe enthält einen der Platzhalter. Ansonsten verwende den Standard gleich Vergleich.

Freundliche Grüße...

2
Josh Stodola

Es kommt wirklich darauf an, was die Abfrage tun soll. Wenn Sie eine exakte Übereinstimmung meinen, verwenden Sie =. Wenn Sie eine verworrene Übereinstimmung meinen, dann verwenden Sie LIKE. Zu sagen, was Sie meinen, ist normalerweise eine gute Richtlinie mit Code.

1
notnot

In Oracle gibt ein "Gefällt mir" ohne Platzhalter das gleiche Ergebnis wie ein "Gleich" zurück, erfordert jedoch möglicherweise zusätzliche Verarbeitung. Laut Tom Kyte behandelt Oracle ein "Gefällt mir" ohne Platzhalter als "Gleich", wenn Literale verwendet werden, aber nicht, wenn Bindevariablen verwendet werden.

1
Chris B

= und LIKE sind nicht dasselbe;

  1. = stimmt mit der genauen Zeichenfolge überein
  2. LIKE stimmt mit einer Zeichenfolge überein, die Platzhalter (%) enthalten kann
0
baretta