我有一个大表,想知道是否可以提高查询的性能。
allDocumentsWithPersianMonth
有25000000
条记录
var normalDocuments = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId != 8 && x.DocumentTypeId != 9);
var debitOpening = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId == 8);
var creditOpening = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId == 8);
var debitClosing = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId == 9);
var creditClosing = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId == 9);
return allDocumentsWithPersianMonth
.GroupBy(x => new { x.DetailId, x.DetailCode, x.DetailDescription, x.PersianMonth })
.Select(g => new AccountsAgingViewModel
{
DetailId = g.Key.DetailId,
DetailCode = g.Key.DetailCode,
DetailDescription = g.Key.DetailDescription,
FarvardinDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 1).Sum(x => x.Debit),
OrdibeheshtDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 2).Sum(x => x.Debit),
KhordadDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 3).Sum(x => x.Debit),
TirDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 4).Sum(x => x.Debit),
MordadDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 5).Sum(x => x.Debit),
ShahrivarDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 6).Sum(x => x.Debit),
MehrDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 7).Sum(x => x.Debit),
AbanDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 8).Sum(x => x.Debit),
AzarDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 9).Sum(x => x.Debit),
DeyDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 10).Sum(x => x.Debit),
BahmanDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 11).Sum(x => x.Debit),
EsfandDebit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 12).Sum(x => x.Debit),
FarvardinCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 1).Sum(x => x.Credit),
OrdibeheshtCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 2).Sum(x => x.Credit),
KhordadCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 3).Sum(x => x.Credit),
TirCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 4).Sum(x => x.Credit),
MordadCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 5).Sum(x => x.Credit),
ShahrivarCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 6).Sum(x => x.Credit),
MehrCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 7).Sum(x => x.Credit),
AbanCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 8).Sum(x => x.Credit),
AzarCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 9).Sum(x => x.Credit),
DeyCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 10).Sum(x => x.Credit),
BahmanCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 11).Sum(x => x.Credit),
EsfandCredit = normalDocuments.Where(x => x.DetailId == g.Key.DetailId && x.PersianMonth == 12).Sum(x => x.Credit),
DebitSumOpening = debitOpening.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Debit),
DebitSumClosing = debitClosing.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Credit),
CreditSumOpening = creditOpening.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Debit),
CreditSumClosing = creditClosing.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Credit),
})
.ToList();
答案 0 :(得分:8)
您应该首先消除相同查询的执行。例如,检查以下方法。我们不是每个月每次迭代normalDocuments
,而是迭代一次,并根据月份对文档进行分组。
然后我们创建一个带有PersianMonth
键的字典,并将Debit
的相应总和值。
这样做我们将从24次迭代变为1次。然后我们定义一个func来从这个字典中获取一个月的借方或贷方的值。从您的模型中,存款可能是借记卡或信用卡。因此,通过传递布尔参数isDebit
,您可以确定是否要读取借方或贷方的值。
此定义可能需要进行一些更改,因为我不知道Debit
和Credit
的类型,我只是假设这是{{1} }}
decimal
答案 1 :(得分:4)
试试这段代码:
var normalDocuments = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId != 8 && x.DocumentTypeId != 9);
var debitOpening = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId == 8);
var creditOpening = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId == 8);
var debitClosing = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId == 9);
var creditClosing = allDocumentsWithPersianMonth.Where(x => x.DocumentTypeId == 9);
return allDocumentsWithPersianMonth
.GroupBy(x => new { x.DetailId, x.DetailCode, x.DetailDescription, x.PersianMonth })
.Select(g =>
{
var filteredDocuments = normalDocuments.Where(x => x.DetailId == g.Key.DetailId);
var m1 = filteredDocuments.Where(x => x.PersianMonth == 1);
var m2 = filteredDocuments.Where(x => x.PersianMonth == 3);
var m3 = filteredDocuments.Where(x => x.PersianMonth == 4);
var m4 = filteredDocuments.Where(x => x.PersianMonth == 5);
var m5 = filteredDocuments.Where(x => x.PersianMonth == 6);
var m6 = filteredDocuments.Where(x => x.PersianMonth == 7);
var m7 = filteredDocuments.Where(x => x.PersianMonth == 8);
var m8 = filteredDocuments.Where(x => x.PersianMonth == 9);
var m9 = filteredDocuments.Where(x => x.PersianMonth == 2);
var m10 = filteredDocuments.Where(x => x.PersianMonth == 10);
var m11 = filteredDocuments.Where(x => x.PersianMonth == 11);
var m12 = filteredDocuments.Where(x => x.PersianMonth == 12);
return new AccountsAgingViewModel
{
DetailId = g.Key.DetailId,
DetailCode = g.Key.DetailCode,
DetailDescription = g.Key.DetailDescription,
FarvardinDebit = m1.Sum(x => x.Debit),
OrdibeheshtDebit = m2.Sum(x => x.Debit),
KhordadDebit = m3.Sum(x => x.Debit),
TirDebit = m4.Sum(x => x.Debit),
MordadDebit = m5.Sum(x => x.Debit),
ShahrivarDebit = m6.Sum(x => x.Debit),
MehrDebit = m7.Sum(x => x.Debit),
AbanDebit = m8.Sum(x => x.Debit),
AzarDebit = m9.Sum(x => x.Debit),
DeyDebit =m10.Sum(x => x.Debit),
BahmanDebit = m11.Sum(x => x.Debit),
EsfandDebit = m12.Sum(x => x.Debit),
FarvardinCredit =m1.Sum(x => x.Credit),
OrdibeheshtCredit = m2.Sum(x => x.Credit),
KhordadCredit = m3.Sum(x => x.Credit),
TirCredit = m4.Sum(x => x.Credit),
MordadCredit = m5.Sum(x => x.Credit),
ShahrivarCredit = m6.Sum(x => x.Credit),
MehrCredit = m7.Sum(x => x.Credit),
AbanCredit = m8.Sum(x => x.Credit),
AzarCredit = m9.Sum(x => x.Credit),
DeyCredit = m10.Sum(x => x.Credit),
BahmanCredit = m11.Sum(x => x.Credit),
EsfandCredit = m12.Sum(x => x.Credit),
DebitSumOpening = debitOpening.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Debit),
DebitSumClosing = debitClosing.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Credit),
CreditSumOpening = creditOpening.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Debit),
CreditSumClosing = creditClosing.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Credit),
};
})
.ToList();
更新
Christos代码比这更好。 我已通过400 recrod Christos代码测试仅需18839毫秒, 我的代码需要102975毫秒。
这是最佳解决方案:
var normalDocuments = allDocumentsWithPersianMonth
.GroupBy(x => new { x.DetailId, x.DetailCode, x.DetailDescription, x.PersianMonth })
.Select(g =>
{
var groupedDocuments = normalDocuments
.Where(x => x.DetailId == g.Key.DetailId)
.GroupBy(x => x.PersianMonth)
.ToDictionary(x => x.Key,
x => new DepositTypes(x.Sum(y => y.Debit), x.Sum(y => y.Credit)));
Func<int, bool, decimal> getValueFunc = (id, isDebit)
=> groupedDocuments.TryGetValue(id, out var value) ? (isDebit ? value.Debit : value.Credit) : 0;
return new AccountsAgingViewModel
{
DetailId = g.Key.DetailId,
DetailCode = g.Key.DetailCode,
DetailDescription = g.Key.DetailDescription,
FarvardinDebit = getValueFunc(1, true),
OrdibeheshtDebit = getValueFunc(2, true),
KhordadDebit = getValueFunc(3, true),
TirDebit = getValueFunc(4, true),
MordadDebit = getValueFunc(5, true),
ShahrivarDebit = getValueFunc(6, true),
MehrDebit = getValueFunc(7, true),
AbanDebit = getValueFunc(8, true),
AzarDebit = getValueFunc(9, true),
DeyDebit = getValueFunc(10, true),
BahmanDebit = getValueFunc(11, true),
EsfandDebit = getValueFunc(12, true),
FarvardinCredit = getValueFunc(1, false),
OrdibeheshtCredit = getValueFunc(2, false),
KhordadCredit = getValueFunc(3, false),
TirCredit = getValueFunc(4, false),
MordadCredit = getValueFunc(5, false),
ShahrivarCredit = getValueFunc(6, false),
MehrCredit = getValueFunc(7, false),
AbanCredit = getValueFunc(8, false),
AzarCredit = getValueFunc(9, false),
DeyCredit = getValueFunc(10, false),
BahmanCredit = getValueFunc(11, false),
EsfandCredit = getValueFunc(12, false),
DebitSumOpening = debitOpening.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Debit),
DebitSumClosing = debitClosing.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Credit),
CreditSumOpening = creditOpening.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Debit),
CreditSumClosing = creditClosing.Where(y => y.DetailId == g.Key.DetailId).Sum(x => x.Credit),
};
答案 2 :(得分:3)
要检查的一些选项: