When using SQL, are there any benefits of using =
in a WHERE
clause instead of LIKE
?
Without any special operators, LIKE
The equals (=) operator is a "comparison operator compares two values for equality." In other words, in an SQL statement, it won't return true unless both sides of the equation are equal. For example:
SELECT * FROM Store WHERE Quantity = 200;
The LIKE operator "implements a pattern match comparison" that attempts to match "a string value against a pattern string containing wild-card characters." For example:
SELECT * FROM Employees WHERE Name LIKE 'Chris%';
LIKE is generally used only with strings and equals (I believe) is faster. The equals operator treats wild-card characters as literal characters. The difference in results returned are as follows:
SELECT * FROM Employees WHERE Name = 'Chris';
And
SELECT * FROM Employees WHERE Name LIKE 'Chris';
Would return the same result, though using LIKE would generally take longer as its a pattern match. However,
SELECT * FROM Employees WHERE Name = 'Chris%';
And
SELECT * FROM Employees WHERE Name LIKE 'Chris%';
Would return different results, where using "=" results in only results with "Chris%" being returned and the LIKE operator will return anything starting with "Chris".
Hope that helps. Some good info can be found here.
=
and LIKE
is not the same;
=
matches the exact string LIKE
matches a string that may contain wildcards (%)LIKE
and =
are different operators. Most answers here focus on the wildcard support, which is not the only difference between these operators!
=
is a comparison operator that operates on numbers and strings. When comparing strings, the comparison operator compares whole strings.
LIKE
is a string operator that compares character by character.
To complicate matters, both operators use a collation which can have important effects on the result of the comparison.
Let's first identify an example where these operators produce obviously different results. Allow me to quote from the MySQL manual:
Per the SQL standard, LIKE performs matching on a per-character basis, thus it can produce results different from the = comparison operator:
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 |
+--------------------------------------+
Please note that this page of the MySQL manual is called String Comparison Functions, and =
is not discussed, which implies that =
is not strictly a string comparison function.
=
Work?The SQL Standard § 8.2 describes how =
compares strings:
The comparison of two character strings is determined as follows:
a) If the length in characters of X is not equal to the length in characters of Y, then the shorter string is effectively replaced, for the purposes of comparison, with a copy of itself that has been extended to the length of the longer string by concatenation on the right of one or more pad characters, where the pad character is chosen based on CS. If CS has the NO PAD attribute, then the pad character is an implementation-dependent character different from any character in the character set of X and Y that collates less than any string under CS. Otherwise, the pad character is a .
b) The result of the comparison of X and Y is given by the collating sequence CS.
c) Depending on the collating sequence, two strings may compare as equal even if they are of different lengths or contain different sequences of characters. When the operations MAX, MIN, DISTINCT, references to a grouping column, and the UNION, EXCEPT, and INTERSECT operators refer to character strings, the specific value selected by these operations from a set of such equal values is implementation-dependent.
(Emphasis added.)
What does this mean? It means that when comparing strings, the =
operator is just a thin wrapper around the current collation. A collation is a library that has various rules for comparing strings. Here's an example of a binary collation from 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);
}
This particular collation happens to compare byte-by-byte (which is why it's called "binary" — it doesn't give any special meaning to strings). Other collations may provide more advanced comparisons.
For example, here is a UTF-8 collation that supports case-insensitive comparisons. The code is too long to paste here, but go to that link and read the body of my_strnncollsp_utf8mb4()
. This collation can process multiple bytes at a time and it can apply various transforms (such as case insensitive comparison). The =
operator is completely abstracted from the vagaries of the collation.
LIKE
Work?The SQL Standard § 8.5 describes how LIKE
compares strings:
The <predicate>
M LIKE P
is true if there exists a partitioning of M into substrings such that:
i) A substring of M is a sequence of 0 or more contiguous <character representation>s of M and each <character representation> of M is part of exactly one substring.
ii) If the i-th substring specifier of P is an arbitrary character specifier, the i-th substring of M is any single <character representation>.
iii) If the i-th substring specifier of P is an arbitrary string specifier, then the i-th substring of M is any sequence of 0 or more <character representation>s.
iv) If the i-th substring specifier of P is neither an arbitrary character specifier nor an arbitrary string specifier, then the i-th substring of M is equal to that substring specifier according to the collating sequence of the <like predicate>, without the appending of <space> characters to M, and has the same length as that substring specifier.
v) The number of substrings of M is equal to the number of substring specifiers of P.
(Emphasis added.)
This is pretty wordy, so let's break it down. Items ii and iii refer to the wildcards _
and %
, respectively. If P
does not contain any wildcards, then only item iv applies. This is the case of interest posed by the OP.
In this case, it compares each "substring" (individual characters) in M
against each substring in P
using the current collation.
The bottom line is that when comparing strings, =
compares the entire string while LIKE
compares one character at a time. Both comparisons use the current collation. This difference leads to different results in some cases, as evidenced in the first example in this post.
Which one should you use? Nobody can tell you that — you need to use the one that's correct for your use case. Don't prematurely optimize by switching comparison operators.
Using = avoids wildcards and special characters conflicts in the string when you build the query at run time.
This makes the programmer's life easier by not having to escape all special wildcard characters that might slip in the LIKE clause and not producing the intended result. After all, = is the 99% use case scenario, it would be a pain to have to escape them every time.
rolls eyes at '90s
I also suspect it's a little bit slower, but I doubt it's significant if there are no wildcards in the pattern.
For this example we take it for granted that varcharcol doesn't contain ''
and have no empty cell against this column
select * from some_table where varcharCol = ''
select * from some_table where varcharCol like ''
The first one results in 0 row output while the second one shows the whole list. = is strictly-match case while like acts like a filter. if filter has no criteria, every data is valid.
like - by the virtue of its purpose works a little slower and is intended for use with varchar and similar data.
If you search for an exact match, you can use both, = and LIKE.
Using "=" is a tiny bit faster in this case (searching for an exact match) - you can check this yourself by having the same query twice in SQL Server Management Studio, once using "=", once using "LIKE", and then using the "Query" / "Include actual execution plan".
Execute the two queries and you should see your results twice, plus the two actual execution plans. In my case, they were split 50% vs. 50%, but the "=" execution plan has a smaller "estimated subtree cost" (displayed when you hover over the left-most "SELECT" box) - but again, it's really not a huge difference.
But when you start searching with wildcards in your LIKE expression, search performance will dimish. Search "LIKE Mill%" can still be quite fast - SQL Server can use an index on that column, if there is one. Searching "LIKE %expression%" is horribly slow, since the only way SQL Server can satisfy this search is by doing a full table scan. So be careful with your LIKE's !
Marc