我有一个我可以建立起来的智慧。当我通过Entity Framework运行它时,运行需要2.5秒。当我获取查询并运行它,或者只是分析数据库并查看EF运行的查询时,它需要< 100毫秒。什么是EF为其他2.49秒做什么,我怎么能阻止它花这么长时间?
我已经尝试过AsNoTracking(),关闭了LazyLoadingEnabled ......
编辑:针对results.ToString()运行秒表与运行查询本身一样长(甚至连续运行.ToString()2x)所以看起来我需要减少生成查询所需的时间本身。
查询,如SQL分析器所示。最新执行时间,87ms:
SELECT
[Project3].[C1] AS [C1],
[Project3].[loan_number] AS [loan_number],
[Project3].[cifno] AS [cifno],
[Project3].[cifnumber] AS [cifnumber],
[Project3].[curr_maturity_date] AS [curr_maturity_date],
[Project3].[total_past_due_balance] AS [total_past_due_balance],
[Project3].[userdef02] AS [userdef02],
[Project3].[userdef05] AS [userdef05],
[Project3].[transaction_amount] AS [transaction_amount],
[Project3].[user_reference] AS [user_reference],
[Project3].[effective_date] AS [effective_date],
[Project3].[userdef03] AS [userdef03],
[Project3].[userdef01] AS [userdef01],
[Project3].[acctrefno] AS [acctrefno],
[Project3].[userdef04] AS [userdef04],
[Project3].[transrefno] AS [transrefno],
[Project3].[C2] AS [C2],
[Project3].[paid_date] AS [paid_date],
[Project3].[check_number] AS [check_number],
[Project3].[transaction_amount1] AS [transaction_amount1]
FROM ( SELECT
[Filter1].[transrefno] AS [transrefno],
[Filter1].[acctrefno1] AS [acctrefno],
[Filter1].[effective_date] AS [effective_date],
[Filter1].[transaction_amount] AS [transaction_amount],
[Filter1].[user_reference] AS [user_reference],
[Filter1].[userdef01] AS [userdef01],
[Filter1].[userdef03] AS [userdef03],
[Filter1].[userdef04] AS [userdef04],
[Filter1].[userdef05] AS [userdef05],
[Extent6].[loan_number] AS [loan_number],
[Extent9].[cifno] AS [cifno],
[Extent13].[cifnumber] AS [cifnumber],
[Extent16].[curr_maturity_date] AS [curr_maturity_date],
[Extent19].[total_past_due_balance] AS [total_past_due_balance],
[Extent23].[userdef02] AS [userdef02],
[Extent46].[paid_date] AS [paid_date],
[Extent50].[check_number] AS [check_number],
[Limit21].[transaction_amount] AS [transaction_amount1],
1 AS [C1],
CAST( [Filter1].[transaction_code] AS int) AS [C2]
FROM (SELECT [Extent3].[transrefno] AS [transrefno], [Extent3].[acctrefno] AS [acctrefno1], [Extent3].[transaction_code] AS [transaction_code], [Extent3].[effective_date] AS [effective_date], [Extent3].[transaction_amount] AS [transaction_amount], [Extent3].[user_reference] AS [user_reference], [Extent3].[userdef01] AS [userdef01], [Extent3].[userdef02] AS [userdef02], [Extent3].[userdef03] AS [userdef03], [Extent3].[userdef04] AS [userdef04], [Extent3].[userdef05] AS [userdef05]
FROM [dbo].[loanacct] AS [Extent1]
INNER JOIN [dbo].[cif] AS [Extent2] ON [Extent1].[cifno] = [Extent2].[cifno]
INNER JOIN [dbo].[loanacct_trans_history] AS [Extent3] ON [Extent1].[acctrefno] = [Extent3].[acctrefno]
WHERE ([Extent2].[cifnumber] IN ('647077')) AND ([Extent3].[userdef03] IN ('sizt7c2IokaTKwQCbdXyaw==', '2VnYfyKBwESZtVhXdXxfXg==', 'sizt7c2IokaTKwQCbdXyaw==', 'sizt7c2IokaTKwQCbdXyaw==', '9CR/EFNaFUqPEx3V/WRVww==')) AND ([Extent3].[userdef03] IS NOT NULL) ) AS [Filter1]
OUTER APPLY (SELECT TOP (1) [Extent4].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent4]
INNER JOIN [dbo].[loanacct] AS [Extent5] ON [Extent4].[acctrefno] = [Extent5].[acctrefno]
WHERE ([Extent5].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent4].[userdef02] = [Filter1].[userdef02]) OR (([Extent4].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit1]
LEFT OUTER JOIN [dbo].[loanacct] AS [Extent6] ON [Filter1].[acctrefno1] = [Extent6].[acctrefno]
OUTER APPLY (SELECT TOP (1) [Extent7].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent7]
INNER JOIN [dbo].[loanacct] AS [Extent8] ON [Extent7].[acctrefno] = [Extent8].[acctrefno]
WHERE ([Extent8].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent7].[userdef02] = [Filter1].[userdef02]) OR (([Extent7].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit2]
LEFT OUTER JOIN [dbo].[loanacct] AS [Extent9] ON [Filter1].[acctrefno1] = [Extent9].[acctrefno]
OUTER APPLY (SELECT TOP (1) [Extent10].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent10]
INNER JOIN [dbo].[loanacct] AS [Extent11] ON [Extent10].[acctrefno] = [Extent11].[acctrefno]
WHERE ([Extent11].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent10].[userdef02] = [Filter1].[userdef02]) OR (([Extent10].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit3]
LEFT OUTER JOIN [dbo].[loanacct] AS [Extent12] ON [Filter1].[acctrefno1] = [Extent12].[acctrefno]
LEFT OUTER JOIN [dbo].[cif] AS [Extent13] ON [Extent12].[cifno] = [Extent13].[cifno]
OUTER APPLY (SELECT TOP (1) [Extent14].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent14]
INNER JOIN [dbo].[loanacct] AS [Extent15] ON [Extent14].[acctrefno] = [Extent15].[acctrefno]
WHERE ([Extent15].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent14].[userdef02] = [Filter1].[userdef02]) OR (([Extent14].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit4]
LEFT OUTER JOIN [dbo].[loanacct] AS [Extent16] ON [Filter1].[acctrefno1] = [Extent16].[acctrefno]
OUTER APPLY (SELECT TOP (1) [Extent17].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent17]
INNER JOIN [dbo].[loanacct] AS [Extent18] ON [Extent17].[acctrefno] = [Extent18].[acctrefno]
WHERE ([Extent18].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent17].[userdef02] = [Filter1].[userdef02]) OR (([Extent17].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit5]
LEFT OUTER JOIN [dbo].[loanacct] AS [Extent19] ON [Filter1].[acctrefno1] = [Extent19].[acctrefno]
OUTER APPLY (SELECT TOP (1) [Extent20].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent20]
INNER JOIN [dbo].[loanacct] AS [Extent21] ON [Extent20].[acctrefno] = [Extent21].[acctrefno]
WHERE ([Extent21].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent20].[userdef02] = [Filter1].[userdef02]) OR (([Extent20].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit6]
LEFT OUTER JOIN [dbo].[loanacct] AS [Extent22] ON [Filter1].[acctrefno1] = [Extent22].[acctrefno]
LEFT OUTER JOIN [dbo].[loanacct_detail] AS [Extent23] ON [Extent22].[acctrefno] = [Extent23].[acctrefno]
OUTER APPLY (SELECT TOP (1) [Extent24].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent24]
INNER JOIN [dbo].[loanacct] AS [Extent25] ON [Extent24].[acctrefno] = [Extent25].[acctrefno]
WHERE ([Extent25].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent24].[userdef02] = [Filter1].[userdef02]) OR (([Extent24].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit7]
OUTER APPLY (SELECT TOP (1) [Extent26].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent26]
INNER JOIN [dbo].[loanacct] AS [Extent27] ON [Extent26].[acctrefno] = [Extent27].[acctrefno]
WHERE ([Extent27].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent26].[userdef02] = [Filter1].[userdef02]) OR (([Extent26].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit8]
OUTER APPLY (SELECT TOP (1) [Extent28].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent28]
INNER JOIN [dbo].[loanacct] AS [Extent29] ON [Extent28].[acctrefno] = [Extent29].[acctrefno]
WHERE ([Extent29].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent28].[userdef02] = [Filter1].[userdef02]) OR (([Extent28].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit9]
OUTER APPLY (SELECT TOP (1) [Extent30].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent30]
INNER JOIN [dbo].[loanacct] AS [Extent31] ON [Extent30].[acctrefno] = [Extent31].[acctrefno]
WHERE ([Extent31].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent30].[userdef02] = [Filter1].[userdef02]) OR (([Extent30].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit10]
OUTER APPLY (SELECT TOP (1) [Extent32].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent32]
INNER JOIN [dbo].[loanacct] AS [Extent33] ON [Extent32].[acctrefno] = [Extent33].[acctrefno]
WHERE ([Extent33].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent32].[userdef02] = [Filter1].[userdef02]) OR (([Extent32].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit11]
OUTER APPLY (SELECT TOP (1) [Extent34].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent34]
INNER JOIN [dbo].[loanacct] AS [Extent35] ON [Extent34].[acctrefno] = [Extent35].[acctrefno]
WHERE ([Extent35].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent34].[userdef02] = [Filter1].[userdef02]) OR (([Extent34].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit12]
OUTER APPLY (SELECT TOP (1) [Extent36].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent36]
INNER JOIN [dbo].[loanacct] AS [Extent37] ON [Extent36].[acctrefno] = [Extent37].[acctrefno]
WHERE ([Extent37].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent36].[userdef02] = [Filter1].[userdef02]) OR (([Extent36].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit13]
OUTER APPLY (SELECT TOP (1) [Extent38].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent38]
INNER JOIN [dbo].[loanacct] AS [Extent39] ON [Extent38].[acctrefno] = [Extent39].[acctrefno]
WHERE ([Extent39].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent38].[userdef02] = [Filter1].[userdef02]) OR (([Extent38].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit14]
OUTER APPLY (SELECT TOP (1) [Extent40].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent40]
INNER JOIN [dbo].[loanacct] AS [Extent41] ON [Extent40].[acctrefno] = [Extent41].[acctrefno]
WHERE ([Extent41].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent40].[userdef02] = [Filter1].[userdef02]) OR (([Extent40].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit15]
OUTER APPLY (SELECT TOP (1) [Extent42].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent42]
INNER JOIN [dbo].[loanacct] AS [Extent43] ON [Extent42].[acctrefno] = [Extent43].[acctrefno]
WHERE ([Extent43].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent42].[userdef02] = [Filter1].[userdef02]) OR (([Extent42].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit16]
OUTER APPLY (SELECT TOP (1) [Extent44].[voucher_id] AS [voucher_id]
FROM [dbo].[loanacct_trans_history] AS [Extent44]
INNER JOIN [dbo].[loanacct] AS [Extent45] ON [Extent44].[acctrefno] = [Extent45].[acctrefno]
WHERE ([Extent45].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent44].[userdef02] = [Filter1].[userdef02]) OR (([Extent44].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit17]
LEFT OUTER JOIN [dbo].[voucher] AS [Extent46] ON [Limit17].[voucher_id] = [Extent46].[voucher_id]
OUTER APPLY (SELECT TOP (1) [Extent47].[voucher_id] AS [voucher_id]
FROM [dbo].[loanacct_trans_history] AS [Extent47]
INNER JOIN [dbo].[loanacct] AS [Extent48] ON [Extent47].[acctrefno] = [Extent48].[acctrefno]
WHERE ([Extent48].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent47].[userdef02] = [Filter1].[userdef02]) OR (([Extent47].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Limit18]
LEFT OUTER JOIN [dbo].[voucher] AS [Extent49] ON [Limit18].[voucher_id] = [Extent49].[voucher_id]
LEFT OUTER JOIN [dbo].[disbursement_check] AS [Extent50] ON [Extent49].[check_id] = [Extent50].[check_id]
OUTER APPLY (SELECT TOP (1) [Filter21].[transaction_amount], [Filter21].[userdef02], [Filter21].[transrefno1]
FROM (SELECT [Extent51].[transaction_amount] AS [transaction_amount], [Extent51].[userdef02] AS [userdef02], [Project1].[transrefno] AS [transrefno1]
FROM [dbo].[loanacct_trans_history] AS [Extent51]
INNER JOIN [dbo].[loanacct] AS [Extent52] ON [Extent51].[acctrefno] = [Extent52].[acctrefno]
LEFT OUTER JOIN (SELECT TOP (1)
[Extent53].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent53]
INNER JOIN [dbo].[loanacct] AS [Extent54] ON [Extent53].[acctrefno] = [Extent54].[acctrefno]
WHERE ([Extent54].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent53].[userdef02] = [Filter1].[userdef02]) OR (([Extent53].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Project1] ON 1 = 1
WHERE ([Extent52].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND ([Extent51].[transaction_code] IN (cast(1000 as decimal(18)), cast(1202 as decimal(18)))) ) AS [Filter21]
LEFT OUTER JOIN (SELECT TOP (1)
[Extent55].[transrefno] AS [transrefno]
FROM [dbo].[loanacct_trans_history] AS [Extent55]
INNER JOIN [dbo].[loanacct] AS [Extent56] ON [Extent55].[acctrefno] = [Extent56].[acctrefno]
WHERE ([Extent56].[cifno] IN (cast(309 as decimal(18)), cast(641 as decimal(18)), cast(60583 as decimal(18)))) AND (([Extent55].[userdef02] = [Filter1].[userdef02]) OR (([Extent55].[userdef02] IS NULL) AND ([Filter1].[userdef02] IS NULL))) ) AS [Project2] ON 1 = 1
WHERE ([Filter21].[userdef02] = (CASE WHEN ([Filter21].[transrefno1] IS NULL) THEN N'' ELSE CAST( [Project2].[transrefno] AS nvarchar(max)) END)) OR (([Filter21].[userdef02] IS NULL) AND (CASE WHEN ([Filter21].[transrefno1] IS NULL) THEN N'' ELSE CAST( [Project2].[transrefno] AS nvarchar(max)) END IS NULL)) ) AS [Limit21]
) AS [Project3]
ORDER BY [Project3].[effective_date] DESC
OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY
查询的主要部分......调用ToList()需要2.5s
var queryable = ApplyQuery(query, nlsContext);
var transactionQueryable = queryable.SelectMany(l => l.loanacct_trans_history);
if (query.UserIds != null)
{
var encodedUserIds = query.UserIds.Select(u => GuidEncoder.Encode(u)).ToList();
transactionQueryable = transactionQueryable.Where(t => encodedUserIds.Contains(t.userdef03));
}
if(query.AdvancesOnly)
{
transactionQueryable = transactionQueryable.Where(t => AdvanceTypes.Contains(t.transaction_code));
}
if (!string.IsNullOrWhiteSpace(query.SortProperty))
{
transactionQueryable = ApplySort(nlsContext, transactionQueryable, query);
}
else
{
transactionQueryable = transactionQueryable.ApplySort(t => t.transaction_reference_no, true);
}
transactionQueryable = transactionQueryable.ApplyPaging(query);
var results = transactionQueryable
.Select(t => new
{
t,
DealerTransaction = nlsContext.loanacct_trans_history
.Where(dth => dealerIds.Contains(dth.loanacct.cif.cifno))
.Where(dth => dth.userdef02 == t.userdef02)
.FirstOrDefault()
})
.Select(o => new TransactionHistoryResult
{
Loan = new Loan
{
AccountNumber = o.t.loanacct.loan_number,
ContactId = o.t.loanacct.cifno,
ContactNumber = o.t.loanacct.cif.cifnumber,
MaturityDate = o.t.loanacct.curr_maturity_date,
PastDue = o.t.loanacct.total_past_due_balance,
ProgramIdString = o.t.loanacct.loanacct_detail.userdef02,
},
Transaction = new Transaction
{
AdminUserId = o.t.userdef05,
Amount = o.t.transaction_amount,
Comment = o.t.user_reference,
EffectiveDate = o.t.effective_date,
EncodedUserId = o.t.userdef03,
InvoiceNumber = o.t.userdef01,
LoanId = o.t.acctrefno,
Product = o.t.userdef04,
RowId = o.t.transrefno,
Type = (Raf.Models.Lending.TransactionType)(int)o.t.transaction_code
},
PaidDate = o.DealerTransaction.voucher.paid_date,
CheckNumber = o.DealerTransaction.voucher.disbursement_check.check_number,
CreditServiceFee = nlsContext.loanacct_trans_history
.Where(csfth => CreditServiceFeeTypes.Contains(csfth.transaction_code))
.Where(csfth => dealerIds.Contains(csfth.loanacct.cif.cifno))
.Where(th => th.userdef02 == o.DealerTransaction.transrefno.ToString())
.FirstOrDefault()
.transaction_amount
});
答案 0 :(得分:0)
“当我抓住查询并运行它时”
从Sql Server Management Studio运行查询时,您使用的是其默认查询执行设置,并不一定与实体框架(ado.net)使用的设置相同。
在Sql Manager中,您可以检查
下的默认设置工具/选项/查询执行/ SQL Server
因此,如果要正确评估查询,则需要从分析器中获取连接设置,并在从sql management studio执行时为查询设置相同的选项。
答案 1 :(得分:0)
Query执行后的下一步是Object Materialization,其中从SQL检索的Table数据被转换为单个对象。
SQL将发送一个包含大量重复值的大表,SQL会快速发送,可能与您对Sql server请求原始sql时同时发送,但EF的实现速度很慢,并且随着许多嵌套而变得越来越慢进行选择。
由于您的查询选择具有嵌套选择,因此EF将需要时间,因为EF必须在内存组中执行,并在内存查询中执行一些操作以构建您请求的图形格式的对象。
当你说查询是82毫秒时,分析你的C#代码将显示它花费大部分时间的位置。
.GroupBy(q => 0)
之类的东西是性能杀手,因为EF将无法将其转换为SQL组,但由于前面有很多复杂的语句,它将在内存组中执行。
在这种情况下,我们可以简单地创建一个视图和/或存储过程来创建可以映射到一个实体中的简单属性的简单表。 EF未经过设计,不建议用作SQL存储过程和强大功能的替代方案。