Azure SQL数据库-相同查询的响应时间截然不同

时间:2019-04-26 22:03:41

标签: sql azure azure-sql-database

我们有一个BI服务,该服务在分别具有60k和140k行的2个表上运行一组查询。该数据库是S2类(50 DTU)单一数据库Azure SQL数据库。

示例查询如下:

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]和[Recipient]表上:

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 Shell运行此查询时,它在200ms内始终返回。

获得此查询的解释计划不包括任何全表/索引扫描,也不建议配置其他索引。

据我们所知,这些查询是作为单进程管道的一部分按顺序运行的,其中命令一次被出队。

什么可以解释这些截然不同的结果?

编辑1

一个难题出现了。在Data Studio Shell中执行时,运行上述查询的以下两种变体会产生截然不同的响应时间:

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'

变体1始终在200毫秒以下返回,而变体2始终在10 s左右返回。

变体2的响应时间与我们在Azure中获得的响应时间更加一致。我们是否可以使用EF Core正确运行查询?

编辑2

以下是查询计划:

Query 1 Query 2

另一个有趣的元素是query1在11:30:05超时,但是在30秒后的11时30分以相同的参数运行了<300ms ...

0 个答案:

没有答案