我正在使用EF4查询oracle数据库。
我有2个表POINTS
(大约有100 000行)和COUNTRIES
,每个点都有一个countryCode
作为外键
我在存储库中有以下两种方法
public List<PointsTable> GetAll()
{
using (Entities context = new Entities())
{
List<PointsTable> theList = context.POINTS_TABLE.ToList();
return theList;
}
}
public List<PointsTable> GetAllComplete()
{
using (Entities context = new Entities())
{
List<PointsTable> theList = context.POINTS_TABLE.Include("Countries").ToList();
return theList;
}
}
GetAll
需要5秒,但GetAllComplete
需要2分钟!
我使用AsParallel()
,但收益很荒谬。
我可以加快速度吗,或者是什么导致它变慢?
答案 0 :(得分:5)
原因是,对于每条记录,您要检索的是200k记录的国家/地区,这些记录会累积到很多的记录中。
您是否打算稍后查询此数据以将其减少到您的特定需求?如果是这样的话,他们还没有.ToList()
。
更改您的存储库方法以返回IQueryable
,这样您就可以将查询限制为稍后需要的特定数据,从而减少您放入记忆中的数据量
private Entities _context;
public PointsRepository(Entities context)
{
_context = context
}
public IQueryable<PointsTable> GetAll()
{
return context.POINTS_TABLE;
}
public IQueryable<PointsTable> GetAllComplete()
{
return context.POINTS_TABLE.Include("Countries");
}
然后,您可以添加特定过滤器,并ToList
更小的结果。 e.g。
using (Entities context = new Entities())
{
var rep = new PointsRepository(context);
// This will change the query you send to sql to only
// retrieve the specific data you want and should result
// in much quicker execution
var result = rep.GetAllComplete() // get all with includes
.Where(p => p.Property = "Specific") // refine the query
.ToList() // retrieve the data and add to memory
}
希望这有帮助
答案 1 :(得分:0)
AS Parallel(),不使用Linq to Entities,只使用Linq to Object。
用EF装载200K不是很好。
您可以通过只读加载来提高性能:
context.POINTS_TABLE.MergeOption = MergeOption.NoTracking;