如何跨多个线程运行动态查询

时间:2017-06-01 09:16:17

标签: sql-server sql-server-2012

我有一个动态查询来重建连接到我们的中央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

1 个答案:

答案 0 :(得分:2)

我能想到的最简单但最简单的方法是为每个索引重建创建一个Sql Server Agent作业,然后逐个启动每个作业。

嘿,我说这是kludgey!:)

涉及大量代码的更好方法是使用Sql Server Service Broker。你可以很快地将一个基本框架放在一起,但是如果你希望它具有弹性,那么你就会花一些时间在它上面。

另一种可能介于两者之间的方法,但涉及用.Net语言编写代码,例如C#,就是编写一个触发异步调用的过程,尽管你可能需要注意为此利用资源。 / p>

您最好的“外部但内部”选项是将索引重建放在SSIS包中,并从脚本中调用它,作为Sql代理作业或直接调用。

TL; DR :Sql Server本身不提供通过T-SQL运行异步查询的任何本机方法。