简体   繁体   English

实体框架6查询性能(MM关系)

[英]Entity Framework 6 Query Performance (M-M Relationship)

I need to query multiple columns from multiple tables using EF. 我需要使用EF从多个表中查询多个列。 All goes well and with nice performance when i don't include a MM Relationship in the select query. 当我在选择查询中不包括MM Relationship时,一切运行良好,并且性能良好。

Query with MM Relationship: MM关系查询:

result = (from s in db.Member
                      .Include(i => i.Category)
                      .Include(i => i.MemberWorkEntity)
                      .Include(i => i.Status)
                      .Include(i => i.DiscountMethod)
                      .Where(i => i.C_deleted == null)
      select new MemberDTO
      {
          memberNumber = s.memberNumber,
          name = s.name,
          status = s.Status.name,
          email = s.email,
          phone = s.phone,
          mobile = s.mobile,
          fax = s.fax,
          workEntity = (from e in db.WorkEntity.Where(i => i.workEntityLevelID == 2)
                        join sc in s.MemberWorkEntity on e.workEntityID equals sc.workEntityID
                        select e.name).FirstOrDefault(),
          category = s.Category.name,
          discountMethod = s.DiscountMethod.name,
          delegate = s.delegate ? "Yes" : "No",
          leader = s.leader ? "Yes" : "No"

      }).AsNoTracking().ToList<MemberDTO>();

30000 records execution time (ms): 30000条记录的执行时间(毫秒):

|1st Execution: 1376
|2nd Execution: 160
|3rd Execution: 145

Query without MM Relationship: 没有MM关系的查询:

result = (from s in db.Member
                      .Include(i => i.Category)
                      .Include(i => i.MemberWorkEntity)
                      .Include(i => i.Status)
                      .Include(i => i.DiscountMethod)
                      .Where(i => i.C_deleted == null)
      select new MemberDTO
      {
          memberNumber = s.memberNumber,
          name = s.name,
          status = s.Status.name,
          email = s.email,
          phone = s.phone,
          mobile = s.mobile,
          fax = s.fax,
          //removed M-M Relationship Query
          category = s.Category.name,
          discountMethod = s.DiscountMethod.name,
          delegate = s.delegate ? "Yes" : "No",
          leader = s.leader ? "Yes" : "No"

      }).AsNoTracking().ToList<MemberDTO>();

30000 records execution time (ms): 30000条记录的执行时间(毫秒):

|1st Execution: 1286
|2nd Execution: 79
|3rd Execution: 67

Why such a difference (2x slower in average)? 为什么会有这样的差异(平均速度慢2倍)? How can i improve the query performance? 如何提高查询性能?

UPDATE: Relationship between Member and WorkEntity 更新:成员和工作实体之间的关系 M-M关系

UPDATE: Updated my query based on @AndreFilimon's suggestion: 更新:根据@AndreFilimon的建议更新了我的查询:

IEnumerable<WorkEntity> workEntities = db.WorkEntity.AsNoTracking().Where(i => i.workEntityLevelID == 2);

result = (from s in db.Member
                      .Include(i => i.Category)                          
                      .Include(i => i.Status)
                      .Include(i => i.DiscountMethod)
                      .Where(i => i.C_deleted == null)
      select new MemberDTO
      {
          memberNumber = s.memberNumber,
          name = s.name,
          status = s.Status.name,
          email = s.email,
          phone = s.phone,
          mobile = s.mobile,
          fax = s.fax,
          workEntity = (from e in workEntities
                        join sc in s.MemberWorkEntity on e.workEntityID equals sc.workEntityID
                        select e.name).FirstOrDefault(),
          category = s.Category.name,
          discountMethod = s.DiscountMethod.name,
          delegate = s.delegate ? "Yes" : "No",
          leader = s.leader ? "Yes" : "No"

      }).AsNoTracking().ToList<MemberDTO>();

30000 records execution time (ms): 30000条记录的执行时间(毫秒):

|1st Execution: 1364
|2nd Execution: 122
|3rd Execution: 120

UPDATE: Added a simple index to my Member table as @agfc suggested: 更新:按照@agfc建议,向我的会员表添加了一个简单索引:

IEnumerable<WorkEntity> workEntities = db.WorkEntity.AsNoTracking().Where(i => i.workEntityLevelID == 2);

result = (from s in db.Member
                      .Include(i => i.Category)                          
                      .Include(i => i.Status)
                      .Include(i => i.DiscountMethod)
                      .Where(i => i.C_deleted == null)
      select new MemberDTO
      {
          memberNumber = s.memberNumber,
          name = s.name,
          status = s.Status.name,
          email = s.email,
          phone = s.phone,
          mobile = s.mobile,
          fax = s.fax,
          workEntity = (from e in workEntities
                        join sc in s.MemberWorkEntity on e.workEntityID equals sc.workEntityID
                        select e.name).FirstOrDefault(),
          category = s.Category.name,
          discountMethod = s.DiscountMethod.name,
          delegate = s.delegate ? "Yes" : "No",
          leader = s.leader ? "Yes" : "No"

      }).AsNoTracking().ToList<MemberDTO>();

30000 records execution time (ms): 30000条记录的执行时间(毫秒):

|1st Execution: 1544
|2nd Execution: 109
|3rd Execution: 105

UPDATE: Changed query based on @Klinger's answer: 更新:基于@Klinger的答案更改了查询:

result = db.MemberWorkEntity.Where(mw => mw.WorkEntity.workEntityLevelID == 2 && mw.Member.C_deleted == null)
        .Select(s => new MemberDTO 
        {
            memberNumber = mw.Member.memberNumber,
            name = mw.Member.name,
            status = mw.Member.Status.name,
            email = mw.Member.email,
            phone = mw.Member.phone,
            mobile = mw.Member.mobile,
            fax = mw.Member.fax,
            workEntity = mw.WorkEntity.name,
            category = mw.Member.Category.name,
            discountMethod = mw.Member.DiscountMethod.name,
            @delegate = mw.Member.@delegate ? "Yes" : "No",
            leader = mw.Member.leader ? "Yes" : "No"
        }).ToList();

30000 records execution time (ms): 30000条记录的执行时间(毫秒):

|1st Execution: 1427
|2nd Execution: 80
|3rd Execution: 76

Without looking at the exact shape of your entities, something like the following should do: 在不查看实体的确切形状的情况下,应执行以下操作:

result = db.MemberWorkEntity.Where(mw => mw.WorkEntity.workEntityLevelID == 2 && mw.Member.C_deleted == null)
        .Select(s => new MemberDTO 
{
  memberNumber = mw.Member.memberNumber,
  name = mw.Member.name,
  status = mw.Member.Status.name,
  email = mw.Member.email,
  phone = mw.Member.phone,
  mobile = mw.Member.mobile,
  fax = mw.Member.fax,
  workEntity = mw.WorkEntity.name,
  category = mw.Member.Category.name,
  discountMethod = mw.Member.DiscountMethod.name,
  @delegate = mw.Member.@delegate ? "Yes" : "No",
  leader = mw.Member.leader ? "Yes" : "No"
}).ToList();

No need to use Include because you are projecting into a DTO not an entity. 无需使用Include因为您要投影到DTO中而不是实体中。 The DTO won't have the navigation properties to the entities you are including. DTO将没有要包含的实体的导航属性。 Include is used for eager loading when entities are returned. Include用于在返回实体时急切加载。

Try to move the includes after the where clause, you should get some overall performance here also: Also move the inner query out of the main query to avoid joins as bellow: 尝试将where子句后的include移到这里,您还应该在这里获得一些整体性能:还将内部查询移出主查询,以避免出现波纹管连接:

var workEntities=(from e in db.WorkEntity).Where(e=>e.workEntityLevelID==2).ToList();
var result = (from s in db.Member.Where(i => i.C_deleted == null).Include(i => i.Category).Include(i => i.MemberWorkEntity).Include(i => i.Status).Include(i => i.DiscountMethod)
          select new MemberDTO
          {
              memberNumber = s.memberNumber,
              name = s.name,
              status = s.Status.name,
              email = s.email,
              phone = s.phone,
              mobile = s.mobile,
              fax = s.fax,
              workEntity = workEntities.Where(e=>e.workEntityID ==sc.workEntityID).DefaultIfEmpty().Select(e=>e.name).FirstOrDefault(),
              category = s.Category.name,
              discountMethod = s.DiscountMethod.name,
              delegate = s.delegate ? "Yes" : "No",
              leader = s.leader ? "Yes" : "No"

          }).AsNoTracking().ToList<MemberDTO>();

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

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