我的查询效果不佳,例如生成的SQL代码是次优的。
原始陈述看起来像这样(简化):
ctx.Table1.Where(t => ...)
.OrderBy(t => ....)
.Select(t => new {Table1 = t,
SomeProperty = t.Table2.SomeProperty,
SomeProperty2 = t.Table2.SomeProperty2,
AnotherProperty = t.Table3.AnotherProperty,
...
}
我查看了SQL Profiler,发现生成的SQL会多次连接同一个表,并且该语句大约需要1秒才能执行。
然后我将声明重写为以下内容:
from t in ctx.Table1
join t2 in ctx.Table2 on t.key equals t2.key into lt2
from t2 in lt2.DefaultIfEmpty()
join t3 in ctx.Table3 on t.key equals t3.key into lt3
from t3 in lt3.DefaultIfEmpty()
where t ...
orderby t...
select new {Table1 = t, .... }
这产生了一个更好的声明,当从SQL分析器中获取并在Management studio中执行时,它的速度是前一个示例中代码生成的语句的两倍。
但是,在运行第二个示例中的代码时,EF生成表达式所花费的时间远远超过了从查询优化中获得的时间。
那么我该如何将第二号语句写成CompiledQuery
。我基本上不知道如何从CompiledQuery
返回匿名类型。
答案 0 :(得分:0)
我发现使用CompiledQueries的解决方法是:
这会强制在开始时编译查询,但是能够以比CompiledQueries更灵活的方式编写查询。
InitQueryX()应该使用多个虚拟输入,以便它覆盖QueryX()方法中的所有路径(类似于单元测试代码覆盖率)。
如果可能,InitQueryX()的输入应该是导致数据库中0行的模拟,这样Init()方法将花费更少的时间来运行。
答案 1 :(得分:0)