【发布时间】:2015-12-22 23:08:28
【问题描述】:
我正在处理一个包含 8000 万 (80,000,000) 行的 SQL Server 表。数据空间 = 198,000 MB。毫不奇怪,针对该表的查询经常会发生变化或超时。为了增加这些问题,表行会相当频繁地更新,并且还会定期添加新行。因此,它像病毒爆发一样继续增长。
我的问题是我想编写 Entity Framework 5 LINQ to Entities 查询来从这个怪物表中获取行。正如我所尝试的那样,超时已成为彻底的流行病。还有一些事情:表的主键已编入索引,并且在其 19 列中的 4 列上具有非聚集索引。
到目前为止,我正在编写使用事务范围和读取未提交隔离级别的简单 LINQ 查询。我尝试增加命令超时和连接超时。我编写了返回 FirstOrDefault() 或集合的查询,如下所示,它试图从当前日期前 7 天获取单个 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 和针对 .NET v4.5 和 SQL Server 2008 R2 的更新 5。
我生成了 EF 生成的 SQL 语句,它看起来并不比上面的 LINQ 语句复杂得多。而且我的大脑很痛。
那么,我是否达到了某种对 EF 的容忍度限制?桌子太大了吗?查询此表时是否应该恢复为存储过程/域方法?我还有其他选择吗?有一些关于删除表格行的讨论,但这可能不会很快发生。我确实阅读了一些关于分页的内容,但我不确定这是否有帮助。任何想法或想法将不胜感激!谢谢!
【问题讨论】:
-
能否展示 EF 生成的查询和表结构,如果可以的话,加上查询计划。
-
第一个问题:您的表上是否有一个 index 包含
te.cr_date列(单独或作为索引中的第一列)?
标签: sql-server linq c#-4.0 entity-framework-5