У нас есть служба BI, которая выполняет набор запросов к 2 таблицам соответственно по 60 и 140 тыс. Строк.База данных представляет собой базу данных Azure SQL с одной базой данных класса S2 (50 DTU).
Пример запроса выглядит следующим образом:
select distinct [t1].[DefinitionId], isnull([t3].[Count], 0) as Count, [t1].[Type]
from [bi].[Trigger] as [t1]
left join (
select [t2].[DefinitionId], count(1) as [Count]
from [bi].[Trigger] as [t2]
inner join [bi].[Recipient] as [r] on [t2].[RecipientId] = [r].[RecipientId] and [r].[IsDeleted] = 0 and [r].[IsDeactivated] = 0 and [t2].[DeliveryStatus] = @deliveryStatus
where [t2].[CampaignId] = @campaignId
group by [t2].[DefinitionId], [t2].[Type]
) as [t3] on [t1].[DefinitionId] = [t3].[DefinitionId]
where [t1].[CampaignId] = @campaignId
Надлежащие индексы расположены как на [Trigger], так и на триггере.Таблицы [Получатель]:
CREATE INDEX [IX_Trigger_CampaignId] on [bi].[Trigger] ([CampaignId]) INCLUDE ([DefinitionId],[Type]);
CREATE INDEX [IX_Trigger_CampaignIdDeliveryStatus] on [bi].[Trigger] ([CampaignId],[DeliveryStatus]) INCLUDE ([DefinitionId],[Type],[RecipientId]);
CREATE INDEX [IX_Recipient_CampaignId] ON [bi].[Recipient] ([CampaignId]);
CREATE INDEX [IX_Recipient_RecipientIdActive] ON [bi].[Recipient] ([RecipientId],[IsDeactivated],[IsDeleted]);
CREATE INDEX [IX_Recipient_Active] ON [bi].[Recipient] ([IsDeactivated],[IsDeleted]) INCLUDE ([RecipientId]);
Запросы выполняются с использованием Entity Framework Core, используя что-то вроде этого:
return await _dbContext
.TriggerCounts
.FromSql(sqlTriggerCountByDeliveryStatus, new SqlParameter("@campaignId", campaignId), new SqlParameter("@deliveryStatus", deliveryStatus))
.ToArrayAsync(ct);
Время ответа на этот запрос варьируется от 10 мс, а иногда и более 30 с, где он простовремя вышло.При выполнении этого запроса из оболочки Azure Data Studio он последовательно возвращается менее 200 мс.
Получение плана объяснения для этого запроса не включает полное сканирование таблицы / индекса и не рекомендует настраивать дополнительные индексы.
Насколько нам известно, эти запросы выполняются последовательно как часть однопроцессного конвейера, где команды снимаются по очереди по очереди.
Чем можно объяснить эти совершенно разные результаты?
Редактировать 1
Возник кусок головоломки.Выполнение этих двух вариантов вышеупомянутого запроса приводит к совершенно разному времени отклика при выполнении в оболочке Data Studio:
1.
declare @campaignId nvarchar(128) = '3155373858485711912C4FC8383061F44488933B942FBF81BB1';
declare @deliveryStatus nvarchar(32) = 'delivered';
select distinct [t1].[DefinitionId], isnull([t3].[Count], 0) as Count, [t1].[Type]
from [bi].[Trigger] as [t1]
left join (
select [t2].[DefinitionId], count(1) as [Count]
from [bi].[Trigger] as [t2]
inner join [bi].[Recipient] as [r] on [t2].[RecipientId] = [r].[RecipientId] and [r].[IsDeleted] = 0 and [r].[IsDeactivated] = 0 and [t2].[DeliveryStatus] = @deliveryStatus
where [t2].[CampaignId] = @campaignId
group by [t2].[DefinitionId], [t2].[Type]
) as [t3] on [t1].[DefinitionId] = [t3].[DefinitionId]
where [t1].[CampaignId] = @campaignId
2.
declare @campaignId nvarchar(128) = '3155373858485711912C4FC8383061F44488933B942FBF81BB1';
declare @deliveryStatus nvarchar(32) = 'delivered';
select distinct [t1].[DefinitionId], isnull([t3].[Count], 0) as Count, [t1].[Type]
from [bi].[Trigger] as [t1]
left join (
select [t2].[DefinitionId], count(1) as [Count]
from [bi].[Trigger] as [t2]
inner join [bi].[Recipient] as [r] on [t2].[RecipientId] = [r].[RecipientId] and [r].[IsDeleted] = 0 and [r].[IsDeactivated] = 0 and [t2].[DeliveryStatus] = 'delivered'
where [t2].[CampaignId] = '3155373858485711912C4FC8383061F44488933B942FBF81BB1'
group by [t2].[DefinitionId], [t2].[Type]
) as [t3] on [t1].[DefinitionId] = [t3].[DefinitionId]
where [t1].[CampaignId] = '3155373858485711912C4FC8383061F44488933B942FBF81BB1'
Variant1 постоянно возвращает менее 200 мс, а вариант 2 - около 10 с.
Время ответа для варианта 2 больше соответствует тому, что мы получаем в Azure.Правильно ли мы выполняем запрос с EF Core?
Изменить 2
Вот планы запроса:
Другим интересным элементом является то, что query1 истек в 11:30:05 по тайм-ауту, но затем работал в <300 мс в 11:30:38, всего 30 секунд спустя, сте же параметры ... </p>