给定针对EF数据上下文的linq查询:
var customers = data.Customers.Where(c => c.EmailDomain.StartsWith(term))
你希望它能像这样产生SQL,对吗?
SELECT {cols} FROM Customers WHERE EmailDomain LIKE @term+’%’
实际上,它确实是这样的:
SELECT {cols} FROM Customer WHERE ((CAST(CHARINDEX(@term, EmailDomain) AS int)) = 1)
你知道为什么吗?
此外,将Where选择器替换为:
c => c.EmailDomain.Substring(0, term.Length) == term
它的运行速度提高了10倍,但仍会产生一些非常令人讨厌的SQL。
注意: Linq to SQL正确地将StartsWith转换为Like {term}%,并且nHibernate具有专用的LikeExpression。
答案 0 :(得分:3)
我不知道MS SQL服务器但是在SQL服务器上紧凑LIKE'foo%'比CHARINDEX快数千倍,如果你在seach列上有INDEX。而现在我正坐着把我的头发拉出来,如何强行使用它。
答案 1 :(得分:2)
原因是,与LIKE相比,CharIndex比SQL更快,更清晰。原因是, 可以 有一些疯狂的“LIKE”条款。例如:
SELECT * FROM Customer WHERE EmailDomain LIKE 'abc%de%sss%'
但是,“CHARINDEX”函数(基本上是“IndexOf”)只处理查找一组字符的第一个实例......不允许使用通配符。
所以,你的答案是:)
编辑:我只是想补充一点,我鼓励人们在他们的SQL查询中使用CHARINDEX来处理他们不需要“LIKE”的事情。需要注意的是,在SQL Server 2000中,“文本”字段可以使用 LIKE 方法,但不能使用CHARINDEX。
答案 2 :(得分:0)
答案 3 :(得分:0)
charindex返回第二个词中第一个词的位置。
sql以1开头作为第一个位置(0 =未找到)
http://msdn.microsoft.com/en-us/library/ms186323.aspx
我不知道为什么它会使用该语法,但这就是它的工作原理
答案 4 :(得分:0)
我同意它并不快,我正在从我们的数据库中检索成千上万的行,并以字母i命名。但我确实发现你需要使用>而不是= ...所以使用
{cols} FROM Customer WHERE ((CAST(CHARINDEX(@term, EmailDomain) AS int)) > 0)
而不是
{cols} FROM Customer WHERE ((CAST(CHARINDEX(@term, EmailDomain) AS int)) = 1)
这是我的两个测试......
select * from members where surname like '%i%' --12 seconds
select * from sc4_persons where ((CAST(CHARINDEX('i', surname) AS int)) > 0) --12 seconds
select * from sc4_persons where ((CAST(CHARINDEX('i', surname) AS int)) = 1) --too few results