当使用SQL,是否有任何收益的使用 = 在一个 WHERE 条款,而不是的 LIKE?

没有任何特别的经营者, LIKE= 都是相同的,对吗?

有帮助吗?

解决方案

不同的运营商

LIKE=不同的运营商。这里大多数的答案集中在通配符支持,这是不是这些运营商之间的唯一区别!

=是,在数字和字符串操作的比较运算符。当比较字符串,则比较操作符进行比较的整个字符串

LIKE是比较逐字符

的字符串操作

要复杂的是,无论是运营商使用归类其可具有在比较的结果产生重要影响。

激励实施例

让我们首先识别一个例子,其中这些运算符产生明显不同的结果。让我从MySQL手册引述如下:

  

每SQL标准,等执行匹配基于每个字符的基础上,从而它可以产生从=比较运算符不同的结果:

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 |
+--------------------------------------+

请注意,MySQL手册的该页面被称为字符串比较函数,和=未讨论的,这意味着=不是严格意义上的字符串比较函数。

如何=工作?

SQL标准§8.2 描述如何=比较字符串:

  

两个字符串的比较被确定如下:

     

a)如果在X的字符的长度不等于长度   Y中的字符,然后将较短的字符串是有效的   替换,比较的目的,与副本   本身一直延伸到的长度越长   字符串通过串联的一个或多个垫的右   字符,其中基于CS选择的填充字符。如果   CS有NO PAD属性,然后填充字符是一个   从任何不同的实现相关的字符   字符的字符集X和Y是整理少   比CS下的任何字符串。否则,填充字符是一个   

     

<强> b)中的X和Y的比较的结果是由给定的   整理序列CS。

     

C)根据排序序列,两个串可以   比较结果为相等,即使它们具有不同的长度或   包含的字符不同的序列。当操作   MAX,MIN,DISTINCT,在分组列引用,以及   UNION,EXCEPT和INTERSECT操作符是指性格   串,从通过这些操作所选择的特定值   一组这样的相等值的是实现相关的。

(着重。)

这是什么意思?这意味着,在比较字符串时,该=运营商仅仅是围绕当前归类的瘦包装。归类是具有用于比较字符串各种规则库。下面是href="https://github.com/mysql/mysql-server/blob/5.7/strings/ctype-bin.c"从MySQL rel="noreferrer">二进制排序

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);
}

这个特定比对情况比较逐字节(这就是为什么它被称为“二进制” - 它没有给出任何特殊含义的字符串)。其它归类可以提供更高级的比较。

例如,这里是一个 UTF-支持不区分大小写的比较核对8 。代码太长,贴在这里,只好到该链接,阅读my_strnncollsp_utf8mb4()的身体。该核对可以一次处理多个字节,其可以应用各种变换(例如,不区分大小写的比较)。该=运营商是完全抽象从核对变化无常。

如何LIKE工作?

SQL标准§8.5 描述如何LIKE比较字符串:

  

在<谓词>

     

M LIKE P

     

如果存在M的分割成子是真   使得:

     

I)M的串是0或更多个连续的序列   <字符表示> M的S和各<字符   >的M个表示正好是一个子串的一部分。

     

ⅱ)如果P的第i子串符是任意   字符指定符,M的第i子串是任何单   <字符表示>

     

ⅲ)如果P的第i子串说明符是任意字符串   符,则M的第i子串是任何序列   0或多个<字符表示>第

     

<强>ⅳ)如果P的第i子串符既不是   任意字符说明符,也不是任意的字符串说明,   然后M的第i子串等于串   根据所述排序序列符   在<像谓词>,而不的追加<空间>   字符M和具有相同的长度为子   说明符。

     

v)的M的子串的数目等于的数   子串P的说明符。

(着重。)

这是很罗嗦,所以让我们把它分解。项II和III分别指的是通配符_%。如果P不包含任何通配符,那么只有第四项适用。这是由所构成OP利益的情况。

在这种情况下,每个“子”(单个字符)在M使用当前归类比较针对每个子串在P

结论

在底线是比较字符串时,=LIKE每次一个字符进行比较整个字符串进行比较。两个比较使用当前的排序规则。这种差别导致在某些情况下不同的结果,如在此后的第一个例子证明。

你应该使用

哪一个?没有人能告诉你 - 你需要使用一个是为您的使用情况下是正确的。不要过早通过切换比较运营商优化。

其他提示

在等于(=)运算符是一个“比较运算符的相等比较两个值”。换句话说,在一个SQL语句,它不会,除非等式的两边相等返回true。例如:

SELECT * FROM Store WHERE Quantity = 200;

LIKE运算符“实现了模式匹配的比较”试图匹配“针对含有通配符的模式字符串的字符串值。”例如:

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

LIKE通常与串和equals(我相信)更快仅使用。等于运算对待通配符作为文字字符。在返回的结果的差异如下:

SELECT * FROM Employees WHERE Name = 'Chris';

SELECT * FROM Employees WHERE Name LIKE 'Chris';

将返回相同的结果,虽然使用LIKE将通常需要更长的时间作为它的一个模式匹配。然而,

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

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

将返回不同的结果,其中,使用“=”仅导致的结果与“克里斯%”被返回等操作者将返回任何开头“克里斯”。

希望有所帮助。一些好的信息可以发现这里

LIKE =是不同的。 LIKE是你会在搜索查询中使用的。它还允许通配符等_(简单字符通配符)和%(多字符通配符)。

如果你想精确匹配

=应使用它会更快。

该站点解释LIKE

这是用于“喜欢”问题 SQL矿的另一个答案的复制/粘贴VS '=' 效果

使用个人例如MySQL的5.5:我有2个表,300万行之一和10000行之一之间的内部联接

当使用像如以下(不含通配符)的索引,花了大约30秒:

where login like '12345678'
使用 '解释'

我得到:

“在这里输入的图像描述”

当使用一个“=”上的相同的查询,花了大约0.1秒时:

where login ='12345678'

使用 '说明' 我得到:

“在这里输入的图像描述”

正如你所看到的,like完全取消了索引查找,所以查询了300倍以上的时间。

一个差别 - 除了使用通配符与LIKE的可能性 - 是在尾部空格:=运算符忽略尾随的空间,但LIKE不

取决于数据库系统上。

一般来说,与没有特殊字符,是,=和LIKE是相同的。

一些数据库系统,但是,可以与不同的运营商不同地对待排序规则设置。

例如,在与对字符串= MySQL的比较是始终不区分大小写默认,所以像不含特殊字符是相同的。在某些其他RDBMS的LIKE是不区分大小写的同时=不

对于这个例子,我们认为理所当然的是varcharcol不含''和具有针对该列没有空细胞

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

第一个结果在0行输出,而第二个示出的整个列表。 =是严格匹配的情况下,同时像像一个滤波器的行为。如果过滤器不具有的标准,每个数据是有效的。

像 - 通过它的目的凭借的作用有点慢,旨在与VARCHAR和类似的数据使用

如果您搜索完全匹配,则可以同时使用,=和LIKE。

使用“=”在这种情况下,一点点更快(搜索精确匹配) - 你可以有相同的查询两次在SQL Server Management Studio中,一旦使用“=”检查这个自己,一旦使用“LIKE ”,然后使用‘查询’/‘包括实际的执行计划。’

执行两个查询,你应该看到结果的两倍,再加上两个实际的执行计划。在我的情况,他们被分成50%和50%,但“=”执行计划有一个更小的“估计子树成本”(当你将鼠标悬停在最左边的“选择”框中显示) - 但是,它确实不是一个巨大的差异。

但是,当你开始在你的LIKE表达通配符搜索,搜索功能将dimish。搜索“LIKE穆勒%”仍然可以说是相当快 - SQL Server可以对列使用索引,如果有的话。搜索“LIKE%表达式%”是可怕的慢,因为只有这样,SQL Server可以满足这个搜索是做一个全表扫描。所以,要小心你的LIKE的!

马克

使用=当你建立在运行时查询避免通配符和一个特殊字符的冲突。

这使得程序员的生活因为不必逃避可能滑倒LIKE子句在不产生预期结果的所有特殊通配符容易。毕竟,=是99%的使用的情况下,这将是一个痛苦每次都逃脱它们。

在20世纪90年代辊眼睛

我也怀疑这是一个稍微慢一点,但我怀疑是否有模式没有通配符它显著。

要解决有关性能的原来的问题,它归结为索引利用率即可。当一个简单的表格的扫描发生时,“喜欢”和“=”是的相同。当索引参与,它的取决于如何形成LIKE子句即可。更具体而言,什么是通配符(S)?

的位置

考虑如下:

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 将取决于两种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 '
  • 使用 MS SQL Server2012年, 尾的空间将可忽略的进行比较,除了与 LIKE 当列类型 VARCHAR.

  • 使用 MySQL5.5, 尾的空间将被忽略 =, 但不对 LIKE,两者都有 CHARVARCHAR.

  • 使用 PostgreSQL9.1, 空间是重大的,与两个 =LIKE 使用 VARCHAR, 但不用 CHAR (见 文档).

    该行为 LIKE 还与不同 CHAR.

    使用相同的数据如上所述,使用明确 CAST 列名 也有差别:

    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)
    

    这只返回的行为"铸都"和"铸col".

LIKE关键字无疑都附带一“性能价格标签”。也就是说,如果你有一个输入字段可能包含通配符在查询中使用,我会建议使用例如输入中包含的外卡之一。否则,使用标准等于比较。

此致...

真的可以归结到你想要的查询做什么。如果你的意思是完全匹配,然后使用=。如果你的意思是一个模糊的匹配,然后使用等。说你的意思是通常与代码的好政策。

在Oracle中,“喜欢”,没有通配符将返回相同的结果作为“等于”,但可能需要额外的处理。 根据汤姆凯特,Oracle将使用绑定变量时治疗“喜欢”,没有通配符作为“等于”使用文字时,但不

=LIKE 是不一样的;

  1. = 匹配确切的字符串
  2. LIKE 匹配的一串可能包含符(%)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top