我们有一个简单的存储过程,该存储过程声明了几个变量,从一些查询计数中设置了变量,然后返回值。存储过程将在.5s内针对sql express(2017)在本地执行。本地数据库是完整的生产备份,已使用与生产相同的数据在本地还原。
当我们在Azure中对同一数据库执行存储过程时,查询将超时并无限期执行。
我尝试执行每个select语句(以下带有select count(distinct ..)的语句,每个语句将在Azure SQL上运行并在大约1s内正确返回计数,但是当我尝试使用声明或我尝试在存储过程中执行选择,如下所示,它们将无法完成。以下代码将无法在Azure上完全执行
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER proc [MySchema].[UserCounts] (
@HUserCount int out
,@NUserCount int out
) as
set @HUserCount = (
select count(distinct userTable.Id) as UserCount
from [MySchema1].[Active] active with (nolock)
inner join [MySchema2].[UserActive] userTable with (nolock) on active.UserId = userTable.Id
inner join [MySchema2].[AppSession] appSession with (nolock) on appSession.UserId = userTable.Id
where appSession.ComponentId = '1'
)
set @NUserCount = (
select count(distinct userTable.Id) as SUserCount
from [MySchema1].[Active] active with (nolock)
inner join [MySchema2].[UserActive] userTable with (nolock) on active.UserId = userTable.Id
inner join [MySchema2].[AppSession] appSession with (nolock) on appSession.UserId = userTable.Id
where appSession.ComponentId = '2'
)
当我执行该过程时,以上代码将挂起/超时。另外,如果我只是从存储过程中拉出代码,它也将无法完成/超时。这是超时的类似代码。
declare @HUserCount int
declare @NUserCount int
select @HUserCount = (
select count(distinct userTable.Id) as UserCount
from [MySchema1].[Active] active with (nolock)
inner join [MySchema2].[UserActive] userTable with (nolock) on active.UserId = userTable.Id
inner join [MySchema2].[AppSession] appSession with (nolock) on appSession.UserId = userTable.Id
where appSession.ComponentId = '1'
)
select @NUserCount = (
select count(distinct userTable.Id) as SUserCount
from [MySchema1].[Active] active with (nolock)
inner join [MySchema2].[UserActive] userTable with (nolock) on active.UserId = userTable.Id
inner join [MySchema2].[AppSession] appSession with (nolock) on appSession.UserId = userTable.Id
where appSession.ComponentId = '2'
)
以下代码将在Azure上按预期执行
select count(distinct userTable.Id) as UserCount
from [MySchema1].[Active] active with (nolock)
inner join [MySchema2].[UserActive] userTable with (nolock) on active.UserId = userTable.Id
inner join [MySchema2].[AppSession] appSession with (nolock) on appSession.UserId = userTable.Id
where appSession.ComponentId = '1'
以及
select count(distinct userTable.Id) as SUserCount
from [MySchema1].[Active] active with (nolock)
inner join [MySchema2].[UserActive] userTable with (nolock) on active.UserId = userTable.Id
inner join [MySchema2].[AppSession] appSession with (nolock) on appSession.UserId = userTable.Id
where appSession.ComponentId = '2'
我缺少明显的东西吗?这些表没有很多行,可能不超过50,000行,对于SQL Server而言几乎没有。
立即编辑/更新和解决方法
作为一个临时解决方案,我修改了存储的proc,以便它不使用set语句,然后再使用select count(distinct ... ...似乎select count(distinct作为独立的语句运行良好,但不能正常运行在set语句之后,该语句将变量设置为select count(distinct ..
这是结果代码/工作代码和经过修改的过程
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER proc [MySchema].[UserCounts] (
@HUserCount int out
,@NUserCount int out
) as
select distinct userTable.Id into #UserCount
from [MySchema1].[Active] active with (nolock)
inner join [MySchema2].[UserActive] userTable with (nolock) on active.UserId = userTable.Id
inner join [MySchema2].[AppSession] appSession with (nolock) on appSession.UserId = userTable.Id
where appSession.ComponentId = '1'
set @HUserCount = (select count(*) from #UserCount)
select distinct userTable.Id into #SUserCount
from [MySchema1].[Active] active with (nolock)
inner join [MySchema2].[UserActive] userTable with (nolock) on active.UserId = userTable.Id
inner join [MySchema2].[AppSession] appSession with (nolock) on appSession.UserId = userTable.Id
where appSession.ComponentId = '2'
set @NUserCount = (select count(*) from #SUserCount)
DROP TABLE #UserCount
DROP TABLE #SUserCount