like子句开头的%

时间:2009-10-08 13:01:00

标签: sql sql-server tsql

我听说由于性能原因,不建议在SQL Server的LIKE子句开头使用%。为什么会这样?

有关此问题的更多详细信息将有助于我了解此问题的影响。

7 个答案:

答案 0 :(得分:13)

%子句开头的LIKE表示索引完全无用。如果有静态文本将模式锚定到%的前面,那么至少可以从索引中获得潜在的效用。

答案 1 :(得分:5)

%foo基本上说“所有字符串以'foo'结尾”。为了过滤掉那些,SQL服务器必须扫描所有表(在最坏的情况下)并检查每个字符串。这就是它如此昂贵的原因。

答案 2 :(得分:5)

为什么LIKE'%......'不好?你不能使用任何索引,必须扫描整个表。

这是一个很好的例子:

  

去电话簿找我   与'%ch'匹配的名称。那会的   因为你不是,所以需要一段时间   能够使用聚集索引,并且必须扫描整本书!

鉴于数据'abcdefg'

WHERE Column1 LIKE '%cde%'  --can't use an index

WHERE Column1 LIKE 'abc%' --can use and index

WHERE Column1 Like '%defg' --can't use an index, but see note below

注意:如果您有需要'%defg'的重要查询,则可以使用持久计算列来REVERSE()列,然后对其进行索引。然后你可以查询:

WHERE Column1Reverse Like REVERSE('defg')+'%' --can use the persistent computed column's index

添加一个持久计算列(反转字符串)并对其进行索引,请使用以下代码:

ALTER TABLE YourTable ADD ReversedYourString  AS REVERSE(YourString) PERSISTED 

CREATE NONCLUSTERED INDEX IX_YourTable_ReversedYourString 
ON YourTable (ReversedYourString) 

答案 3 :(得分:2)

将它放在任何地方会增加性能消耗,因为文本字段的内容没有索引。

在开始时,它必须在最坏的情况下搜索到文本字段的末尾。

答案 4 :(得分:2)

如果在子句的开头有%,则查询引擎无法生成使用索引但必须进行表扫描的查询计划。

答案 5 :(得分:1)

很多人都解释了为什么像'%......'这样的col1很糟糕。

如果你经常遇到这种情况,这是一个潜在的解决方法:

  • 创建另一列,例如col2
  • 在插入/更新col1时写入一个触发器,用col1“向后”填充col2
  • 在col2上创建索引
  • 如果您的应用程序必须搜索col1,如'%...',请搜索col2,如'...%'(或甚至substr(col1等)='...'[原谅我的oracle方言]

我们用它来搜索VIN(车辆识别码)或SocialSecurity号码的最后一位数字,效果很好!性能提升非常好

答案 6 :(得分:0)

全桌扫描

DBA最担心的事情;)

由于索引无法加速搜索,服务器必须循环遍历表中的每条记录(=表扫描)并检查记录是否与LIKE表达式匹配。

这对于小型表来说可能不是问题,但对于包含大量行的大型表来说当然也不是问题,因为所有记录都必须从磁盘中提取。

这与索引扫描相反,其中搜索条件允许服务器使用索引将搜索限制为(理想情况下)一小组记录。