【发布时间】:2013-04-30 08:30:20
【问题描述】:
我在我的数据访问层上使用实体框架 5、ObjectContext 和 POCO。我有一个通用的存储库实现,并且我有一个使用 Skip() 和 Take() 通过分页查询数据库的方法。一切正常,除了跳过很多行时查询性能很慢(我说的是 170k 行)
这是我对 Linq to Entities 的查询的摘录:
C# 代码:
ObjectContext oc = TheOBJEntitiesFactory.CreateOBJEntitiesContext(connection);
var idPred = oc.CreateObjectSet<view_Trans>("view_Trans").AsQueryable();
idPred = idPred.OrderBy(sortColumn, sortDirection.ToLower().Equals("desc"));
var result = idPred.Skip(iDisplayStart).Take(iDisplayLength);
return new PagedResult<view_Trans>(result, totalRecords);
在 Transact-SQL 的翻译查询中,我注意到不是直接在视图中使用 ROW_NUMBER() 子句,而是直接创建子查询并应用 ROW_NUMBER() 到子查询的结果...
示例:
select top(10) extent1.A, extent1.B.extent1.C from (
select extent1.A, extent1.B, extent1.C,
row_number() OVER (ORDER BY [Extent1].[A] DESC) AS [row_number]
from (
select A,B,C from table as extent1)) as extent1
WHERE [Extent1].[row_number] > 176610
ORDER BY [Extent1].[A] DESC
这大约需要 165 秒才能完成。关于如何提高翻译后查询语句的性能的任何想法?
【问题讨论】:
-
由于没有 Skip 的查询很快,这表明问题出在 SQL 中,而不是实体框架中的其他性能考虑方面。因此,我要做的第一件事就是使用 SQL Profiler 来诊断查询缓慢的原因。你试过这个吗?你发现了什么?
-
我已经这样做了。我认为问题出在 Entity Framework 构建的不必要的子查询中,当我使用 LinqToSql 而不是 Entity Framework 进行相同的查询时,结果不一样,查询速度要快得多(约 30 秒)。如果您在上面的示例中看到 Sql,则表明对表有不必要的子查询,并且 row_number 并未应用于表,而是应用于该子查询的结果。
-
我添加了一个 row_number
-
好的,现在你到了某个地方。通过数据库优化顾问运行该查询并查看它的建议。
-
我刚刚使用 SQL Tunning Advisor 运行查询并创建了该工具推荐的两个索引。现在查询速度很快,这解决了我的问题。但无论如何,我认为应该改进实体名声生成的查询。你检查过 LinqToSql 生成的查询吗?
标签: c# entity-framework entity-framework-5 poco