Почему этот запрос Linq to Entities такой медленный, когда на самом деле выполняется на веб-сайте - PullRequest
0 голосов
/ 23 сентября 2018

У меня есть веб-сайт, который получает данные с использованием Linq-to-entity.

Большую часть времени он работает нормально, но в этом случае запрос выполняется от 6 до 30 секунд, когда он фактически выполняется как частьсайт на Azure.

Но это не имеет смысла.Когда я запускаю веб-сайт на своем компьютере разработчика, в окне отладки сообщается, что это занимает 126 миллисекунд.Так почему огромная разница при работе на производстве.

Выполнение запроса в SSMS занимает около 3 секунд.Он получает очень небольшой объем данных, и он не очень сложен, поэтому он действительно должен быть менее секунды.

Это запрос, сообщаемый окном отладки для сервера sql:

FrameworkCore.Database.Command: Information: Executed DbCommand (126ms) [Parameters=[@__ef_filter__CurrentTenantId_0='?' (DbType = Int32), @__parentId_0='?' (DbType = Int32), @__entityStatusId_1='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT [b].[Id], [b].[AssignedToId], [b].[BaselineEndDate], [b].[BaselineStartDate], [b].[Budget], [b].[CloseDate], [b].[CloseStatusId], [b].[Cost], [b].[Description], [b].[Details], [b].[DueDate], [b].[Duration], [b].[EntityStatusId], [b].[ImportanceTypeId], [b].[Inserted], [b].[InsertedBy], [b].[ItemTypeId], [b].[Name], [b].[Note], [b].[OwnedById], [b].[ParentId], [b].[Predecessor], [b].[PriorityTypeId], [b].[Progress], [b].[Risk], [b].[SortOrder], [b].[StartDate], [b].[StatusTypeId], [b].[TenantId], [b].[TimeEstimate], [b].[TimeScaleTypeId], [b].[Updated], [b].[UpdatedBy]
FROM [Items] AS [b]
LEFT JOIN [PriorityTypes] AS [a.PriorityType] ON [b].[PriorityTypeId] = [a.PriorityType].[Id]
INNER JOIN [ItemTypes] AS [a.ItemType] ON [b].[ItemTypeId] = [a.ItemType].[Id]
WHERE ([b].[TenantId] = @__ef_filter__CurrentTenantId_0) AND (([b].[ParentId] = @__parentId_0) AND ([b].[EntityStatusId] = @__entityStatusId_1))
ORDER BY [a.ItemType].[SortOrder], CASE
    WHEN [b].[SortOrder] IS NOT NULL
    THEN 0 ELSE 1
END, [b].[SortOrder], CASE
    WHEN [b].[PriorityTypeId] IS NOT NULL
    THEN 0 ELSE 1
END, CASE
    WHEN [b].[PriorityTypeId] IS NOT NULL
    THEN [a.PriorityType].[SortOrder] ELSE 1000000
END, [b].[Name]

Это linq:

IQueryable<Item> query =
                this.DbContext.Items
                .OrderBy(a => a.ItemType.SortOrder).
                ThenBy(a => a.SortOrder != null ? 0 : 1).  //First, Put Non-Nulls at the top before nulls
                ThenBy(a => a.SortOrder). //Now Sort the non-nulls by SortOrder
                ThenBy(a => a.PriorityTypeId != null ? 0 : 1). //First put the non-null Priority Type at the top before nulls
                ThenBy(a => a.PriorityType != null ? a.PriorityType.SortOrder : 1000000). //Now Sort by Priority Type
                ThenBy(a => a.Name)
                .Where(a => a.ParentId == parentId && a.EntityStatusId == entityStatusId);

Чтобы ускорить это, я попытался повысить уровень обслуживания SQL Server, а также уровень обслуживания веб-сайта до дорогой версии, но он не сделалразница в качестве самых дешевых версий.

Буду признателен за любые советы по повышению производительности (однако никаких стероидов).

Обновление Мне удалось значительно улучшить производительность с помощьюa Выберите, который выбирает подмножество данных:

IQueryable<ChildItemInfo> query = 
                this.DbContext.Items
                .OrderBy(a => a.ItemType.SortOrder).
                ThenBy(a => a.SortOrder != null ? 0 : 1).  //First, Put Non-Nulls at the top before nulls
                ThenBy(a => a.SortOrder). //Now Sort the non-nulls by SortOrder
                ThenBy(a => a.PriorityTypeId != null ? 0 : 1). //First put the non-null Priority Type at the top before nulls
                ThenBy(a => a.PriorityTypeId != null ? a.PriorityType.SortOrder : 1000000). //Now Sort by Priority Type
                ThenBy(a => a.Name)
                .Where(a => a.ParentId == parentId && a.EntityStatusId == entityStatusId).
                Select(i => new ChildItemInfo() { 
                    Id = i.Id,
                    AssignedToName = i.AssignedToId != null ? i.AssignedTo.ApplicationUser.FullName : null,
                    OwnedByName = i.OwnedBy.ApplicationUser.FullName, 
                    Budget = i.Budget,
                     CloseDate = i.CloseDate,
                     CloseStatusName = i.CloseStatus !=null ? i.CloseStatus.Name : "",
                     ItemTypeId = i.ItemTypeId,
                     ItemTypeIcon = i.ItemType.Icon,
                     ImportanceTypeDescription = i.ImportanceType != null ? i.ImportanceType.Description: "",
                     EntityStatusId = i.EntityStatusId,
                     DueDate = i.DueDate,
                     Cost = i.Cost,
                     ItemTypeShowProperties = i.ItemType.ShowProperties,
                     ItemTypeSortOrder = i.ItemType.SortOrder,
                     PriorityTypeDescription = i.PriorityType != null ? i.PriorityType.Description : "",
                     ParentId = i.ParentId,
                     Name = i.Name,
                     PriorityTypeId = i.PriorityTypeId,
                     Progress = i.Progress,
                     SortOrder = i.SortOrder,
                     StartDate = i.StartDate,
                     StatusTypeName = i.StatusType.Name,
                     TimeEstimate = i.TimeEstimate,
                     TimeScaleTypeName = i.TimeScaleType.Name
                });
...