简体   繁体   English

实体框架中的linq查询太慢

[英]The linq query in Entity Framework is too slow

I am using EF6 (model-first) that connects to Oracle 11G. 我正在使用连接到Oracle 11G的EF6(模型优先)。

I have 3 tables A,B,C, and I defined the right FK to get the relationships: 我有3个表A,B,C,并且定义了正确的FK以获取关系:

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

Now, I'm running the following code (using eager loading) to get A with B and C: 现在,我正在运行以下代码(使用紧急加载)来获取带有B和C的A:

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

As you can see I use include and select to eagerly retrieve A with its B's and the B with its C's. 如您所见,我使用include并选择急切地检索A及其B和B及其C。

My problem is that it takes around 4 seconds to run the FirstOrDefault() method. 我的问题是,运行FirstOrDefault()方法大约需要4秒钟。

I have tested it on TOAD, and the generated SQL executed in less than one second. 我已经在TOAD上对其进行了测试,并且生成的SQL在不到一秒钟的时间内执行了。

The retrieved object (ie populated A), is not so big (A has 5 B's and each B has 2 C's, and each table has ~10 columns). 检索到的对象(即填充的A)不是很大(A有5个B,每个B有2个C,每个表有约10列)。

Is there a way to improve the performance? 有没有办法提高性能?

I think that in your case .Include( a => aBSelect( y => yC ) ) will execute another separate SELECT for every row in your result-set, which is suboptimal, instead you should (generally) SELECT from the most descendant table first, then use Include to INNER JOIN any parent data that you need. 我认为在您的情况下.Include( a => aBSelect( y => yC ) )将对结果集中的每一行执行另一个单独的SELECT ,这是次优的,而不是(通常)应从最后代的表中进行SELECT 。首先,然后使用“ IncludeINNER JOIN您需要的任何父数据。

Try this query instead: 请尝试以下查询:

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

Also, check your indexes. 另外,检查索引。

Eventually, to solve the slowness issue, I selected only the columns that I was interested in, and put it into a DTO. 最终,为了解决速度慢的问题,我只选择了我感兴趣的列,并将其放入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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM