实体框架中的linq查询太慢了

时间:2016-12-08 08:33:16

标签: c# performance entity-framework

我正在使用连接到Oracle 11G的EF6(模型优先)。

我有3个表A,B,C,我定义了正确的FK来获得关系:

1. B is a child of A.
2. C is a child of B.

现在,我正在运行以下代码(使用预先加载)来获取A和B和C:

var myQuery = from r in MyContext.A
                                 .Include(x => x.B.Select(y => y.C))
                                 .Where(a => a.sku == 2);
var res = myQuery.FirstOrDefault();

正如你所看到的,我使用include和select来急切地检索A的B和B的C。

我的问题是运行FirstOrDefault()方法需要大约4秒钟。

我在TOAD上测试了它,生成的SQL在不到一秒的时间内执行。

检索到的对象(即填充的A)不是那么大(A有5个B,每个B有2个C,每个表有~10列)。

有没有办法改善表现?

2 个答案:

答案 0 :(得分:0)

我认为在您的情况下,.Include( a => a.B.Select( y => y.C ) )会为结果集中的每一行执行另一个单独的SELECT,这是次优的,而您应该(通常)SELECT来自最首先是后代表,然后使用IncludeINNER JOIN您需要的任何父数据。

请尝试此查询:

 var query = context.C
    .Include( c => c.B )
    .Include( c => c.B.A )
    .Where( c => c.B.A.sku == 2 );
return query.FirstOrDefault();

另外,检查索引。

答案 1 :(得分:0)

最终,为了解决缓慢问题,我只选择了我感兴趣的列,并将其放入DTO。

var myQuery = from r in MyContext.A
                             .Include(x => x.B.Select(y => y.C))
                             .Where(a => a.sku == 2)
                              Select new MyDTO
                              {
                                 ...
                              }
var res = myQuery.FirstOrDefault();