【发布时间】:2016-07-18 09:50:05
【问题描述】:
我遇到了一个问题,即 EF 在搜索字符串字段时会创建糟糕的查询。它产生了一个懒惰程序员风格的查询,包含强制扫描整个索引的空检查。
考虑以下查询。
-
查询 1
var p1 = "x"; var r1 = ctx.Set<E>().FirstOrDefault( subject => p1.Equals(subject.StringField)); -
查询 2
const string p2 = "x"; var r2 = ctx.Set<E>().FirstOrDefault( subject => p2.Equals(subject.StringField));
查询 1 产生
WHERE (('x' = [Extent2].[StringField]) OR (('x' IS NULL) AND ([Extent2].[StringField] IS NULL)))
并在 4 秒内执行
查询 2 产生
WHERE (N'x' = [Extent2].[StringField])
并在 2 毫秒内执行
有没有人知道任何变通方法? (no参数不能是const,因为它是由用户输入的,但不能为null。)
N.B 分析时,两个查询均由 EF 使用 sp_executesql 准备;因为如果它们刚刚被执行,查询优化器将否定 OR 'x' IS NULL 检查。
【问题讨论】:
-
你试过
subject.StringField == p1吗? -
是的。我尝试了每一个变化。我写 p1.Equals 的原因是试图欺骗 EF p1 不能为空,否则会抛出空引用异常
-
这是 Paul white 的回答..stackoverflow.com/questions/17323547/…,我不确定可能有帮助
-
查询 1 通常不是导致 SQL Server 出现问题的模式。它通常被视为与此处的相交版本相同sqlblog.com/blogs/paul_white/archive/2011/06/22/…
标签: c# sql-server entity-framework