EFを使用して複数のテーブルから複数の列を照会する必要があります。選択クエリにM-M関係を含めないと、すべてうまくいって素晴らしいパフォーマンスが得られます。 MM関係にEntity Framework 6クエリパフォーマンス(M-M関係)
クエリ:
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レコードの実行時間(ミリ秒):MM関係せず
|1st Execution: 1376
|2nd Execution: 160
|3rd Execution: 145
クエリ:
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レコードの実行時間(ミリ秒) :
|1st Execution: 1286
|2nd Execution: 79
|3rd Execution: 67
なぜこのような違いが(平均2倍遅いのですか)?どのようにしてクエリのパフォーマンスを向上させることができますか?
UPDATE:
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レコードの実行時間(ミリ秒):
@ AndreFilimonの提案に基づいて、私のクエリを更新:メンバーとWorkEntityUPDATEとの関係
|1st Execution: 1364 |2nd Execution: 122 |3rd Execution: 120
UPDATE:@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レコードの実行時間(ミリ秒):
|1st Execution: 1544
|2nd Execution: 109
|3rd Execution: 105
UPDATE:クリンガーの答え@に基づいて変更クエリ:
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 = [email protected] ? "Yes" : "No",
leader = mw.Member.leader ? "Yes" : "No"
}).ToList();
30000レコードの実行時間(ミリ秒):
|1st Execution: 1427
|2nd Execution: 80
|3rd Execution: 76
投影内に結合を含むサブクエリが含まれていますが、当然遅くなります – Tuco
Member.MemberWorkEntityとWorkEntityの間の直接のナビゲーションはありませんか? (あなたは1つを追加できますか?)、select内でそのjoinクエリを実行しないでください。これは、選択された各項目のループで実行されるためです。 –
@Tuco自然にそれは遅くなる、私の質問は私がそれがより速くなるために私のクエリにどのような変更を加えることができるかです。 – Ricky