当使用SQL时,在WHERE子句中使用=而不是LIKE有任何好处吗?
没有任何特殊的运算符,LIKE和=是一样的,对吧?
当使用SQL时,在WHERE子句中使用=而不是LIKE有任何好处吗?
没有任何特殊的运算符,LIKE和=是一样的,对吧?
当前回答
除了通配符,=和LIKE之间的区别还取决于SQL服务器的类型和列类型。
举个例子:
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 '
Using MS SQL Server 2012, the trailing spaces will be ignored in the comparison, except with LIKE when the column type is VARCHAR. Using MySQL 5.5, the trailing spaces will be ignored for =, but not for LIKE, both with CHAR and VARCHAR. Using PostgreSQL 9.1, spaces are significant with both = and LIKE using VARCHAR, but not with CHAR (see documentation). The behaviour with LIKE also differs with CHAR. Using the same data as above, using an explicit CAST on the column name also makes a difference: 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) This only returns rows for "CAST both" and "CAST col".
其他回答
实际上,这取决于您希望查询做什么。如果你的意思是精确匹配,那么使用=。如果你的意思是一个模糊匹配,那么使用LIKE。对代码来说,表达自己的意思通常是一个很好的策略。
取决于数据库系统。
通常没有特殊字符,是的,=和LIKE是一样的。
但是,某些数据库系统可能会对不同的操作符使用不同的排序设置。
例如,在MySQL中,字符串上的=默认情况下总是不区分大小写的,所以没有特殊字符的LIKE是一样的。在其他一些RDBMS上,LIKE是不区分大小写的,而=则不是。
除了通配符,=和LIKE之间的区别还取决于SQL服务器的类型和列类型。
举个例子:
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 '
Using MS SQL Server 2012, the trailing spaces will be ignored in the comparison, except with LIKE when the column type is VARCHAR. Using MySQL 5.5, the trailing spaces will be ignored for =, but not for LIKE, both with CHAR and VARCHAR. Using PostgreSQL 9.1, spaces are significant with both = and LIKE using VARCHAR, but not with CHAR (see documentation). The behaviour with LIKE also differs with CHAR. Using the same data as above, using an explicit CAST on the column name also makes a difference: 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) This only returns rows for "CAST both" and "CAST col".
要解决最初关于性能的问题,可以归结为索引利用率。当进行简单的表扫描时,“LIKE”和“=”是相同的。当涉及到索引时,这取决于LIKE子句是如何形成的。更具体地说,通配符的位置是什么?
考虑以下几点:
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
当使用"="和"LIKE"时,在查询计划的创建中也可能存在可以忽略不计的差异。
=和LIKE是不一样的;
=匹配精确的字符串 LIKE匹配可能包含通配符的字符串(%)