我们使用实体框架进行数据库访问,并且当我们“思考” LIKE语句时-它实际上会生成CHARINDEX内容。因此,这里是2个简单的查询,在我简化它们以证明我们特定服务器上的观点之后:

-- Runs about 2 seconds
SELECT * FROM LOCAddress WHERE Address1 LIKE '%1124%'
-- Runs about 16 seconds
SELECT * FROM LOCAddress WHERE ( CAST(CHARINDEX(LOWER(N'1124'), LOWER([Address1])) AS int)) = 1


该表现在包含约10万条记录。 Address1是VarChar(100)字段,没什么特别的。

这是两个计划的并排。没有任何意义,分别显示50%和50%,但是执行时间像1:8
performance - CHARINDEX与LIKE搜索的效果大不相同,为什么呢?-LMLPHP

我在网上搜索过,一般建议是使用CHARINDEX而不是LIKE。根据我们的经验,这是相反的。我的问题是什么原因造成的?如何在不更改代码的情况下解决该问题?

最佳答案

我将回答我自己的问题,因为很难找到正确的答案,并且SQL Server 2012执行计划输出已指出了该问题。正如您在原始问题中看到的那样-表面上一切看起来都很好。这是SQL Server 2008。

当我在2012年运行相同的查询时,在CHARINDEX查询中收到警告。问题是-SQL Server必须执行类型转换。 Address1VarChar,查询的N'1124'是Unicode或NVarChar。如果我这样更改此查询:

SELECT *
FROM LOCAddress
WHERE (CAST(CHARINDEX(LOWER('1124'), LOWER([Address1])) AS int))


然后,它与LIKE查询运行相同。因此,由Entity Framework生成器引起的类型转换导致这种可怕的性能下降。

10-08 06:29