2016-08-18 20 views
0

私はSQLのエキスパートではないと言います。私の質問を確認するために事前に感謝します。新しいレコードをリンクサーバーに転送するストアドプロシージャ接続が切断される

新しいレコードをテーブルに転送する途中で、リンクされたサーバーへの接続が定期的に失われるストアドプロシージャに問題があります(多くのレコード)。私はいくつかの事について疑問に思います。

まず、より高速で効率的なタスクを完了するには、より良い方法がありますか?

そして第二に、より良い、それはいくつかがある可能性の場合には15かそこら分を待った後、中断したところから続けるための努力で再試みる前のステップにしようとする接続の損失を処理する方法がありますリンクされたサーバーとの一時的な切断(終了する前に許可されている以上に持続する可能性があります)また、強調表示のステップのようなものは、SQLはリンクサーバーに対して実行されている場合は、場所を取り、接続が失われた、または再接続して、タイムアウト期間継続するためのSQL試行を行うとき、私は、好奇心が強い

これは比較文なので、それはちょうど壊れていますか?私はそれがどのように動作するのか本当に分かりません。

UPDATE [LINKEDSERVER.XYZ.COM].dest_database1.dbo.run 
    SET last_result = 32 
    WHERE type = 158; 

BEGIN TRY 
    INSERT INTO [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table1 (CID , BID , Question1 , Question2 , Question3 , Question4 , Question5 , Question6 , Question7 , Question8 , Question9 , Question10 , Comments , EmailAddress , Name , Address , Address2 , City , State , Zip) 
    SELECT src.CID , src.BID , src.Question1 , src.Question2 , src.Question3 , src.Question4 , src.Question5 , src.Question6 , src.Question7 , src.Question8 , src.Question9 , src.Question10 , src.Comments , src.EmailAddress , src.Name , src.Address , src.Address2 , src.City , src.State , src.Zip 
     FROM table1 AS src LEFT OUTER JOIN [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table1 AS dst ON src.CID = dst.CID AND src.BID = dst.BID 
     WHERE dst.CID IS NULL; 

    INSERT INTO [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table2 (CID , AccountNumber , Name , Address , Address2 , City , State , Zip , BShort, EmailAddress) 
    SELECT src.CID , src.AccountNumber , src.Name , src.Address , src.Address2 , src.City , src.State , src.Zip , src.BShort, src.EmailAddress 
     FROM table2 AS src LEFT OUTER JOIN [LINKEDSERVER.XYZ.COM].[dest_database2].dbo.table2 AS dst ON src.BShort = dst.BShort 
     WHERE dst.BShort IS NULL; 
END TRY 
BEGIN CATCH 
    SELECT @ErrorCode = @@Error; 
    SELECT @ErrorResult = 109; 
    SELECT @ErrorMessage = 'Failed Copy ' + CAST (@ErrorCode AS varchar) ; 
    GOTO ExitWithError; 
END CATCH; 

INSERT INTO [LINKEDSERVER.XYZ.COM].dest_database1.dbo.system_log (notes , log_type , source_type , parent_id) 
VALUES ('Copied tables xyz ' , 45 , 58 , 0) ; 

UPDATE [LINKEDSERVER.XYZ.COM].dest_database1.dbo.run 
    SET last_result = 31 
    WHERE type = 158; 

私は接続が失われた場合ことを理解し、私のcatchブロックを:ここで

は、通常、(最初のステップは、内のcatchブロックを開始)最初のINSERT文で発生し、接続損失が最も一般的ですセクションです実行されないので、ExitWithErrorは使用されません。そして、私は接続が失われたときに、ロールバックが発生することを理解していると思います(リンクされたサーバで動作する場合、どのように/レコードの一部が転送されるので、どのように動作するかはわかりません)。またはbegin catchブロック全体の後のステートメント。私は、これが発生した場合に、何かをログに記録して、ストアドプロシージャが実行されたとき(成功するまで30分ごとに実行するように設定されている)、最初にコードがあるので、最後のステータス/ログエントリを探し、何をすべきかを決定します。 これを処理するより良い方法はありますか?

答えて

0

だから最初のヒントは、可能であれば、他のサーバー(宛先)からストアドプロシージャを実行します。つまり、ローカルサーバーとリンクサーバーを切り替えます。理由は、リンクされたサーバーからローカル・テーブルへのDML(挿入/更新/削除)コマンドのパフォーマンスが大幅に向上したためです。リンクされたテーブルにDMLを実行すると、パフォーマンスが悪くなります。

次は、IDを効果的に使用します。あなたは、サーバ間で大きなテーブルを結合するのではなく、宛先サーバにあるものの最大値を取ることができますか?

シーケンシャルにカウントできない場合は、ソースサーバー上に一時テーブルを作成して、テーブル全体でそれを実行しようとする代わりにフィルターをかけることができます。 idsの場合は、XMLをnvarchar形式で前後に渡すこともできます。または、ソース上にトラッキングテーブルを維持して、insert文のOUTPUT inserted.id INTO ....を使用して、どのIDがすでに処理されているかを知ることができます。

最後に、プロシージャをバッチ/カットアップに設定し、トランザクションをSELECT TOP xレコードなどの小さな塊で一度に実行します。あなたはまだループ全体に配置することができるので、procを1回実行するだけで済むようになりますが、より小さな管理可能な部分でトランザクションを実行することができます。

+0

ソースサーバーは非常に安全なファイアウォールの内側にあり、公開することができないため、代わりに別のサーバーがデータを取得できます。少なくとも私はそれが事実だと思います。 IDは数値でも順序もありません。しかし、おそらく私は新しいものを作ることができます。私はこれを見て、提案をいただきありがとうございます。 あなたの3番目と4番目の提案は面白いです。 OUTPUT inserted.id INTO ...の使用についてもう少し詳細を教えてください。 また、接続が失われたとき実際に何が起こったのか分かりませんか? SQLは単に実行を停止するか、それともより良い処理方法がありますか? ありがとうございました。 – sds

+0

トランザクションがロールバックされ、一時テーブルがメモリから消去されると、接続が失われます。ここには、inserted.idの出力がhttp://stackoverflow.com/questions/6292154/output-to-temporary-table-in-sql-server-2005にリンクされています。私は今週末に時間があれば、3〜4までは大きな話題ですが、結局戻ってくるかもしれません。限り、ファイアウォール私はリンクサーバーにプッシュするよりもむしろリンクサーバーから取得するパフォーマンスの大きな影響になることを確認することをお勧めします。 – Matt

+0

あなたの出身地と目的地にいることについて、あなたは何通の記録をしていますか? – Matt

関連する問題