[英]Linq Query slow with Count. SQL query is very fast. What am I doing wrong?
我有一個非常基本的親子關系。 對於我的主頁,我只想從 children 表中獲取計數。
var assignmenTotal = new AssignmentUser
{
IsSupervisor = supervisor,
AssignmentTotals = (
from a in db.Assignments
where (StartDate.HasValue)
? DbFunctions.TruncateTime(a.CreatedDate) == StartDate
: a.IsArchived == false
orderby a.ID ascending
join b in db.Adjustments on a.ID equals b.AssignmentID
group b by new {a.ID,a.UserName,a.Status,a.CreatedDate,a.IsArchived}
into g
select new AssignmentTotals
{
ID = g.Key.ID,
UserName = g.Key.UserName,
Status = g.Key.Status,
ImportedDate = DbFunctions.TruncateTime(g.Key.CreatedDate),
StartingLocation = (db.Adjustments
.Where(x => x.AssignmentID == g.Key.ID)
.OrderBy(x => x.LocationID)
.Select(x => x.LocationID)
.FirstOrDefault()),
EndingLocation = (db.Adjustments.
Where(x => x.AssignmentID == g.Key.ID)
.OrderByDescending(x => x.LocationID)
.Select(x => x.LocationID)
.FirstOrDefault()),
TotalLocations = g.Count(x => x.LocationID != null),
TotalLicensePlates = g.Count(x => x.ExpectedLicensePlateID != null),
TotalAdjCompleted = g.Count(x => x.Status == "C"),
IsSameUser = (currUser == g.Key.UserName ? true : false),
IsArchived = g.Key.IsArchived
})
.OrderBy(x => x.ID)
.ToList()
};
現在展平的總行數約為 1000,這大約需要 10 秒才能完成。 如果我寫一個 SQL 查詢
SELECT ID, UserName, Status, b.StartLocation, b.EndLocation, b.TotalLocations,
b.TotalLicensePlates, b.TotalLocations
FROM Assignments a
INNER JOIN(
SELECT AssignmentID,
min(LocationID) as StartLocation, max(LocationID) as EndLocation,
COUNT(CASE WHEN LocationID is NOT NULL THEN 1 ELSE 0 end) AS TotalLocations,
SUM(CASE WHEN ExpectedLicensePlateID IS NOT NULL THEN 1 ELSE 0 END )TotalLicensePlates,
SUM(CASE WHEN Status = 'C' THEN 1 ELSE 0 END )TotalAdjCompleted
FROM dbo.Adjustments
group by AssignmentID
) b on (a.ID = b.AssignmentID)
WHERE convert(date,a.CreatedDate) ='04/23/2021'
這需要不到一秒鍾的時間來完成。
我認為我的問題出在 linq COUNT 部分。 我試過做一個子查詢,但仍然很慢。 我認為問題在於 linq 查詢將所有數據帶到客戶端並在客戶端完成所有工作,而不是讓服務器完成所有工作?
有一個更好的方法嗎?
編輯:我正在使用實體框架,當我檢查 SQL 分析器時,SQL 發送非常長且復雜。
實體框架(就像任何其他程序化 Object 關系映射器一樣)的性能和效率越差,您的請求越復雜。
所以,選項:
這里的問題是,您編寫了非等效的 LiNQ 查詢。 在投影中沒有最佳預測如何處理FirstOrDefault
。 它會創建額外的 OUTER APPLY 連接,但速度很慢。
重寫您的查詢,使其盡可能接近 SQL:
var query =
from a in db.Assignments
where (StartDate.HasValue)
? DbFunctions.TruncateTime(a.CreatedDate) == StartDate
: a.IsArchived == false
orderby a.ID ascending
join b in db.Adjustments on a.ID equals b.AssignmentID
group b by new {a.ID,a.UserName,a.Status,a.CreatedDate,a.IsArchived}
into g
select new AssignmentTotals
{
ID = g.Key.ID,
UserName = g.Key.UserName,
Status = g.Key.Status,
ImportedDate = DbFunctions.TruncateTime(g.Key.CreatedDate),
StartingLocation = g.Min(x => x.LocationID)
EndingLocation = g.Max(x => x.LocationID),
TotalLocations = g.Count(x => x.LocationID != null),
TotalLicensePlates = g.Count(x => x.ExpectedLicensePlateID != null),
TotalAdjCompleted = g.Count(x => x.Status == "C"),
IsSameUser = (currUser == g.Key.UserName ? true : false),
IsArchived = g.Key.IsArchived
};
var totals = query
.OrderBy(x => x.ID)
.ToList();
var assignmenTotal = new AssignmentUser
{
IsSupervisor = supervisor,
AssignmentTotals = totals
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.