私は、2つのテーブル(ユーザーのテーブル(3700人)とユーザーが作成した見積もりのテーブル(280000人))を参照する本番データベースでスクリプトを実行しています。Quoteは、アプリケーションのメインオブジェクトであり、非常に大きなオブジェクトであり、多くのデータテーブルが作成されて入力されます。私の目標は、少数のユーザーグループで作成されたものを除くすべての引用からデータベースをクリーンアップすることです。
最初にそれらのユーザーのIDを含む一時テーブルを作成し(スクリプトでも他の方法で使用されます)、次にメインテーブルを実行するカーソルで引用符が一覧表示されます。ユーザーグループから作成された引用符については、必要なクレンジング。
このスクリプトは約26時間実行されることがわかります。これは、データベースの復元に一般に約15分かかるため、独特だと思います。最も重いSQLがそこで実行されると思います。ただし、dbの重量は100GBを超えます。
私が作成しているスクリプトの一部がひどく最適ではないか、またはこれをはるかに短い実行で実行する方法についての提案がありますか?
SQL Server2008R2を実行しています。
これがスクリプトのスケッチです。
CREATE table #UsersIdsToStay(user_id int)
INSERT INTO #UsersIdsToStay
select user_id
from users
where user_name like '%SOMESTRING '
-----
declare @QuoteId int
declare @UserId int
declare QuoteCursor cursor for
select DISTINCT QuoteId, UserId
from QuotesTable
where UserId not in
(
select * from #UsersIdsToStay
)
open QuoteCursor
while 1=1
begin
fetch QuoteCursor into @QuoteId, @UserId
if @@fetch_status != 0 break
-- all the deletions from related tables are executed here using @QuoteId and @UserId
exec('delete from QuoteHistory where QuoteId = ' + @QuoteId + ' and UserId = ' + @UserId )
exec('delete from QuoteRevisions where QuoteId = ' + @QuoteId + ' and UserId = ' + @UserId )
exec('delete from QuoteItems where QuoteId = ' + @QuoteId + ' and UserId = ' + @UserId )
....
end
close QuoteCursor;
deallocate QuoteCursor