Я перебираю все свои базы данных и объединяю результаты в базу данных агрегатов.
В моем цикле я звоню
master.dbo.xp_cmdshell osql C:\whatever.SQL
По мере прохождения цикла, командная оболочка занимает все больше и больше времени для выполнения. Если я останавливаю цикл и запускаю один агрегат для одной базы данных, он выполняется быстро.
Могу ли я что-нибудь добавить в свой внешний скрипт SQL, чтобы он работал быстрее? Может быть, что-то зафиксировать и освободить записи перед следующим циклом? Или я должен добавить какую-то паузу после каждого цикла?
Я хочу использовать внешний файл SQL, потому что он содержит много операторов обновления, и он более управляем для меня.
Вот как я делаю цикл:
Update dbFoo.dbo.tblBar set Processed = 0
Go
WHILE EXISTS ( SELECT ID FROM dbFoo.dbo.tblBar WHERE Processed = 0)
BEGIN
SELECT @aRow = MIN(tblBar.ID) FROM dbFoo.dbo.tblBar
SELECT @aFoo1 = Foo1 FROM dbFoo.dbo.tblBar WHERE ID = @aRow
SELECT @aFoo2 = Foo2 FROM dbFoo.dbo.tblBar WHERE ID = @aRow
SELECT @aFoo3 = Foo3 FROM dbFoo.dbo.tblWhatever WHERE Foo = @aFoo
EXEC RunPreAgg @Foo1 = @aFoo1, @Foo2 = @aFoo2, @Foo3 = @aFoo3, @RetVal = @aRetVal OUTPUT
SELECT returning = @aRetVal
UPDATE dbFoo.dbo.tblBar SET Processed = 1 WHERE ID = @aRow
END
Тогда хранимая процедура RunPreAgg в основном делает это:
if db_id('db' + @Foo1 + '_' + @Foo2) is not null
BEGIN
--This bat file creates the SQL File
select @sql = 'master.dbo.xp_cmdshell '''+@path+'wwwRunPreAgg.bat ' + @Foo1 + ' ' + @Foo2 + ' ' + @Foo3 + ''''
exec( @sql )
--execute
select @sql = 'master.dbo.xp_cmdshell ''osql -E -o '+@path+'output\tmp'+@Foo1+'_'+@Foo2+'.txt -i '+@path+'tmp' + @Foo1 + '.SQL'''
exec( @sql )
--This erases the SQL File
select @sql = 'master.dbo.xp_cmdshell '''+@path+'wwwCleanup.bat ' + @Foo1 + ' ' + @Foo2 + ''''
exec( @sql )
Set @retval = 'Done!'
END
ELSE
BEGIN
Set @retval = 'Err: No DataBase'
END
Имена переменных изменены, чтобы защитить невинных. Код работает нормально, мне просто нужно оптимизировать.