我有一个动态查询来重建连接到我们的中央SQL Server并包含在列表中的所有链接服务器上的索引和统计信息。它工作得很好,但如果在单独的spid上运行它们可以更快地完成,那么它会串行运行,因为它是正在进行工作的远程服务器。 有没有办法改变脚本以允许它们并行运行,而不是等待每个脚本依次完成?
WITH TillNames as (select * from (values
('[DEVELOPERSVR]', '100', 'AD01'),
('[TESTSVR1]', '100', 'AD02'),
('[TESTSVR2]', '100', 'AD03'),
('[TESTSVR3]', '100', 'AD04') -- and two hundred more.
) a ([TillName], [Branch], [TillDesc])) -- Branch and Till Desc used for other purposes, removed here
select * INTO #tills from TillNames
declare @TillName as nvarchar(20), @Branch as nvarchar(5), @TillDesc as nvarchar(100)
declare @sql as nvarchar(max)
declare mycursor cursor for Select [TillName], [Branch], [TillDesc] from #tills
declare @query as nvarchar(max)
open mycursor
fetch next from mycursor into @TillName, @Branch, @TillDesc
while @@FETCH_STATUS=0
BEGIN
set @sql = 'USE [LOCALDB]
Declare @TBname nvarchar(255), @SQL nvarchar(max)
select @TBname = min(TABLE_NAME) from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE=''''BASE TABLE''''
while @TBname is not null
BEGIN
begin try
set @SQL=''''ALTER INDEX ALL ON ['''' + @TBname + ''''] REBUILD; ''''
SET @SQL = @SQL + N''''UPDATE STATISTICS ['''' + @TBname + ''''] WITH FULLSCAN; ''''
EXEC SP_EXECUTESQL @SQL
end try
begin catch
print ''''DID NOT WORK: '''' + @SQL
end catch
select @TBname = min(TABLE_NAME) from INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE=''''BASE TABLE'''' and TABLE_NAME > @TBname
END'
set @query = N'EXEC (''' + @sql + N''') AT ' + @TillName
exec (@query)
fetch next from mycursor into @TillName, @Branch, @TillDesc
END
close mycursor
deallocate mycursor
drop table #tills
答案 0 :(得分:2)
我能想到的最简单但最简单的方法是为每个索引重建创建一个Sql Server Agent作业,然后逐个启动每个作业。
嘿,我说这是kludgey!:)
涉及大量代码的更好方法是使用Sql Server Service Broker。你可以很快地将一个基本框架放在一起,但是如果你希望它具有弹性,那么你就会花一些时间在它上面。
另一种可能介于两者之间的方法,但涉及用.Net语言编写代码,例如C#,就是编写一个触发异步调用的过程,尽管你可能需要注意为此利用资源。 / p>
您最好的“外部但内部”选项是将索引重建放在SSIS包中,并从脚本中调用它,作为Sql代理作业或直接调用。
TL; DR :Sql Server本身不提供通过T-SQL运行异步查询的任何本机方法。