尝试使用EF 5

时间:2015-12-22 23:08:29

标签: sql-server linq c#-4.0 entity-framework-5

我正在使用包含8000万(80,000,000)行的SQL Server表。数据空间= 198,000 MB。毫不奇怪,针对此表的查询经常会流失或超时。要添加问题,表行会相当频繁地更新,并且还会定期添加新行。因此它继续像病毒爆发一样成长。

我的问题是我想编写Entity Framework 5 LINQ to Entities查询以从这个怪物表中获取行。正如我所尝试的那样,超时已成为彻头彻尾的流行病。还有一些事情:表的主键是索引的,它在19列中的4列上都有非聚集索引。

到目前为止,我正在编写使用Transaction Scope和Read Uncommitted Isolation Level的简单LINQ查询。我尝试过增加命令超时和连接超时。我编写了返回FirstOrDefault()的查询或一个集合,例如以下集合,它试图从当前日期之前的七天抓取一个ID(一个int):

public int GetIDForSevenDaysAgo(DateTime sevenDaysAgo)
{
    using (var txn = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
    {                
        var GetId = from te in _repo.GetTEvents()
                    where te.cr_date > sevenDaysAgo
                    orderby te.cr_date
                    select te.id;

        return GetId.FirstOrDefault();
    }
}

public IEnumerable<int> GetIDForSevenDaysAgo(DateTime sevenDaysAgo)
{
    using (var txn = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted }))
    {                
        var GetId = from te in _repo.GetTEvents()
                    where te.cr_date > sevenDaysAgo
                    orderby te.cr_date
                    select te.id;

        return GetId.Take(1);
    }
}

无论超时设置如何,每个查询都会重复超时。我正在使用Unity DI的存储库模式,并使用IQueryable<>调用获取表。我也将存储库调用从当前日期限制为八天(希望只获取这个庞大的表所需的子集)。我正在使用Visual Studio 2013和Update 5针对.NET v4.5和SQL Server 2008 R2。

我生成了EF生成的SQL语句,它看起来并不比上面的LINQ语句复杂得多。我的大脑很疼。

那么,我是否达到EF的某种容忍限度?桌子太大了吗?查询此表时,我应该还原到存储过程/域方法吗?还有其他我应该探索的选择吗?有一些关于删除表的行的讨论,但这可能不会很快发生。我确实读过一些关于分页的内容,但我不确定这是否会有所帮助。任何想法或想法将不胜感激!谢谢!

2 个答案:

答案 0 :(得分:0)

我可以看到您只选择数据并且不会更改数据。那么为什么需要使用TransactionScope?只有在代码中有2个或更多SaveChanges()并且希望它们在一个事务中时,才需要它。所以摆脱它。

我在你的案例中使用的另一件事是禁用更改跟踪和自动检测上下文的更改。但是如果你不在每个请求上对你的上下文进行直观描述,请小心。它可以预先保存旧数据。

要做到这一点,你应该在你的上下文初始化附近写下这行:

context.ObjectTrackingEnabled = false;
context.DeferredLoadingEnabled = false;

您应该考虑的另一件事是pagenation和Cache。但正如我在你的例子中所看到的那样,你只想获得一排。所以不能说什么特别的东西。

我建议您阅读this article以进一步优化。

答案 1 :(得分:0)

如果你必须使用存储过程或EF,这是不容易的,因为我们代表一个怪物。 :-)

我要做的第一件事是在显示实际执行计划的SSMS中运行查询。有时它会提供有关可能会提高性能的索引缺失信息。

从您的示例中,我非常确定您需要该日期列的索引。

换句话说,如果您有权访问 - 请确保表格设计最适合该数据量。

我的想法是,如果一个简单的查询挂起,EF可以做什么呢?