【问题标题】:SQL LIKE with no wildcards the same as '='?没有通配符的 SQL LIKE 与 '=' 一样吗?
【发布时间】:2010-09-29 02:06:00
【问题描述】:

我知道这是一个非常基本的问题,我认为我知道答案...但我想确认一下。

这些查询真的等价吗?

SELECT * FROM FOO WHERE BAR LIKE 'X'
SELECT * FROM FOO WHERE BAR ='X'

在没有通配符的情况下使用 like 可能会产生性能开销?

我有一个可以选择使用 LIKE 和通配符的应用。 SP 当前执行类似操作并附加通配符 - 我正在考虑更新查询以使用 like 但让应用程序根据需要附加通配符。

【问题讨论】:

    标签: sql wildcard sql-like


    【解决方案1】:

    任何好的优化器都会将第一个表达式减少到第二个。

    【讨论】:

    • 好吧,也许吧,但如果它是一个重复使用查询计划的参数化查询,并且参数有时有通配符,有时没有,那不一定是一个好主意。无论哪种方式,都不应该有性能损失。
    • @le dorfier:我同意,在一般情况下是这样。在上面非常具体和狭窄的情况下,这对优化器来说很容易。
    • 我不太确定优化是否可以处理 parm 查询,因为 like 不会使用任何索引
    • LIKE 使用索引,只要搜索字符串的开头没有通配符。
    【解决方案2】:

    正如@ocdecio 所说,如果优化器足够聪明,应该没有区别,但是如果您想确定幕后发生的事情,您应该比较两个查询的执行计划。

    【讨论】:

    • 非常正确,执行计划是你的朋友。
    • 也要小心,因为这可能与索引有关。
    • 这是错误的答案。 LIKE 不仅有性能开销,而且还有逻辑上的差异。请参阅下面 CSharpie 的答案。
    【解决方案3】:

    herehereMatt Whitfield 的原始答案

    =LIKE 之间存在差异。当您使用LIKE 执行字符串比较时,模式字符串中的所有字符都是有效的。这包括前导或尾随空格。

    因此,如果您有一列是 charnchar 而不是 nvarcharvarchar,则由于尾随空格会产生不同的结果。

    重现这种行为的小例子:

    CREATE TABLE #temp (nam [varchar](MAX))
    INSERT INTO [#temp] ([nam])
    VALUES ('hello')
    INSERT INTO [#temp] ([nam])
    VALUES ('hello  ')
    
    SELECT * FROM #temp WHERE [nam] = 'hello  '
    
    SELECT * FROM #temp WHERE [nam] LIKE 'hello  '
    

    【讨论】:

    • 重要提示。当使用 LIKE vs = 使用参数而不是嵌入值(应该这样做)运行此查询时,EQUAL 搜索的性能要好得多。这是因为使用 LIKE 的查询不知道参数是否包含通配符,因此必须执行全索引扫描而不是索引查找或键查找。我了解这个问题中的查询不使用参数,但我想说明这一点,因为使用参数对于帮助避免 SQL 注入攻击很重要。
    • 还有性能损失:LIKE 花费的时间是 '=' 的约 1.45 倍。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    相关资源
    最近更新 更多