Entity Framework 中的查询比直接 sql 中的查询花费的时间更长
Query in Entity Framework takes longer than direct sql
主要问题是,当我在 SQL Management studio 中执行某个查询时,大约需要 2 秒。当通过 entity framework 执行时,我用分析器查看它,查询需要 260 秒。结果只有 72 行 1 个整数。此查询是根据用户定义的过滤器构建的。
有没有人有任何建议可能是错误的?
我在探查器中看到的 sqlquery 如下:
SELECT [Distinct1].[PersonID] AS [PersonID]
FROM (SELECT DISTINCT [Extent1].[PersonID] AS [PersonID]
FROM (SELECT [PersonViewWithExtraInfo].[PersonID] AS [PersonID],
[PersonViewWithExtraInfo].[DateTime] AS [DateTime],
[PersonViewWithExtraInfo].[ExtraInfo1] AS [ExtraInfo1],
[PersonViewWithExtraInfo].[ExtraInfo2] AS [ExtraInfo2],
[PersonViewWithExtraInfo].[ExtraInfo3] AS [ExtraInfo3],
[PersonViewWithExtraInfo].[ExtraInfo4] AS [ExtraInfo4]
FROM [core].[PersonViewWithExtraInfo].AS [PersonViewWithExtraInfo].AS [Extent1]
LEFT OUTER JOIN [core].[Persons] AS [Extent2]
ON [Extent1].[PersonID] = [Extent2].[PersonID]
WHERE ([Extent1].[ExtraInfo4] = 1)
AND(([Extent2].[FirstName] = 'Steven' /* @p__linq__0 */)
OR (([Extent2].[FirstName] IS NULL)
AND ('Steven' /* @p__linq__0 */ IS NULL))
OR ([Extent2].[FirstName] = 'Steffi' /* @p__linq__1 */)
OR (([Extent2].[FirstName] IS NULL)
AND ('Steffi' /* @p__linq__1 */ IS NULL))
OR ([Extent2].[FirstName] = 'Evy' /* @p__linq__2 */)
OR (([Extent2].[FirstName] IS NULL)
AND ('Evy' /* @p__linq__2 */ IS NULL)))
AND ([Extent1].[DateTime] >= '2014-06-01T00:00:00' /* @p__linq__3 */)
AND ([Extent1].[DateTime] <= '2015-05-31T00:00:00' /* @p__linq__4 */)) AS [Distinct1]
我构建了我的 where 子句来比较这样的字符串:
public static Expression<Func<string, bool>> ConvertToExpression(this FilterComparer comparer, string compareValue)
{
switch (comparer)
{
case FilterComparer.IsEqualTo:
return x => x == compareValue;
...
编辑:我找到了问题所在。当我从 sqlprofiler 获取查询时,查询被一个 exec sp_executesql 包围,当我将其粘贴到管理工作室时,查询花费的时间与 EF 一样长。因此,当我删除此查询中的空检查时,延迟就消失了。当他说 'too many expressions per where clause' 时,我应该听听 EF 分析器的意见。唯一的问题是 entity framework 添加了 null 检查。我怎样才能防止这种情况发生?
编辑:这是我从 Linq Insight 获得的 linq 查询。
(from x in ((ObjectQuery<PersonViewWithExtraInfo>)PersonViewWithExtraInfo).MergeAs(0)
where x.ExtraInfo4 && (((False || (True && (x.Person.FirstName == compareValue))) || (True && (x.Person.FirstName == compareValue))) || (True && (x.Person.FirstName == compareValue)))
where (x.DateTime >= startDate.Date) && (x.DateTime <= endDate.Date)
select x.PersonID).Distinct()
正确的和错误的存在,因为查询是根据用户定义的过滤器动态构建的。
所以问题是 EF 正在向查询添加空检查,这使得 where 子句变大了。
通过设置
Configuration.UseDatabaseNullSemantics = true;
在 DbContext 上问题已解决!
主要问题是,当我在 SQL Management studio 中执行某个查询时,大约需要 2 秒。当通过 entity framework 执行时,我用分析器查看它,查询需要 260 秒。结果只有 72 行 1 个整数。此查询是根据用户定义的过滤器构建的。
有没有人有任何建议可能是错误的? 我在探查器中看到的 sqlquery 如下:
SELECT [Distinct1].[PersonID] AS [PersonID]
FROM (SELECT DISTINCT [Extent1].[PersonID] AS [PersonID]
FROM (SELECT [PersonViewWithExtraInfo].[PersonID] AS [PersonID],
[PersonViewWithExtraInfo].[DateTime] AS [DateTime],
[PersonViewWithExtraInfo].[ExtraInfo1] AS [ExtraInfo1],
[PersonViewWithExtraInfo].[ExtraInfo2] AS [ExtraInfo2],
[PersonViewWithExtraInfo].[ExtraInfo3] AS [ExtraInfo3],
[PersonViewWithExtraInfo].[ExtraInfo4] AS [ExtraInfo4]
FROM [core].[PersonViewWithExtraInfo].AS [PersonViewWithExtraInfo].AS [Extent1]
LEFT OUTER JOIN [core].[Persons] AS [Extent2]
ON [Extent1].[PersonID] = [Extent2].[PersonID]
WHERE ([Extent1].[ExtraInfo4] = 1)
AND(([Extent2].[FirstName] = 'Steven' /* @p__linq__0 */)
OR (([Extent2].[FirstName] IS NULL)
AND ('Steven' /* @p__linq__0 */ IS NULL))
OR ([Extent2].[FirstName] = 'Steffi' /* @p__linq__1 */)
OR (([Extent2].[FirstName] IS NULL)
AND ('Steffi' /* @p__linq__1 */ IS NULL))
OR ([Extent2].[FirstName] = 'Evy' /* @p__linq__2 */)
OR (([Extent2].[FirstName] IS NULL)
AND ('Evy' /* @p__linq__2 */ IS NULL)))
AND ([Extent1].[DateTime] >= '2014-06-01T00:00:00' /* @p__linq__3 */)
AND ([Extent1].[DateTime] <= '2015-05-31T00:00:00' /* @p__linq__4 */)) AS [Distinct1]
我构建了我的 where 子句来比较这样的字符串:
public static Expression<Func<string, bool>> ConvertToExpression(this FilterComparer comparer, string compareValue)
{
switch (comparer)
{
case FilterComparer.IsEqualTo:
return x => x == compareValue;
...
编辑:我找到了问题所在。当我从 sqlprofiler 获取查询时,查询被一个 exec sp_executesql 包围,当我将其粘贴到管理工作室时,查询花费的时间与 EF 一样长。因此,当我删除此查询中的空检查时,延迟就消失了。当他说 'too many expressions per where clause' 时,我应该听听 EF 分析器的意见。唯一的问题是 entity framework 添加了 null 检查。我怎样才能防止这种情况发生?
编辑:这是我从 Linq Insight 获得的 linq 查询。
(from x in ((ObjectQuery<PersonViewWithExtraInfo>)PersonViewWithExtraInfo).MergeAs(0)
where x.ExtraInfo4 && (((False || (True && (x.Person.FirstName == compareValue))) || (True && (x.Person.FirstName == compareValue))) || (True && (x.Person.FirstName == compareValue)))
where (x.DateTime >= startDate.Date) && (x.DateTime <= endDate.Date)
select x.PersonID).Distinct()
正确的和错误的存在,因为查询是根据用户定义的过滤器动态构建的。
所以问题是 EF 正在向查询添加空检查,这使得 where 子句变大了。 通过设置
Configuration.UseDatabaseNullSemantics = true;
在 DbContext 上问题已解决!