.NET Webアプリケーションに、プラットフォーム上のユーザーがアカウントをクリアする(つまり、すべてのデータを削除する)ことができるルーチンがあります。このルーチンはストアドプロシージャで実行され、基本的に関連するデータテーブルをループして、作成したさまざまなアイテムをすべてクリアします。
ストアドプロシージャは次のようになります。
ALTER procedure [dbo].[spDeleteAccountData](
@accountNumber varchar(30) )
AS
BEGIN
SET ANSI_NULLS ON ;
SET NOCOUNT ON;
BEGIN TRAN
BEGIN TRY
DELETE FROM myDataTable1 WHERE accountNumber = @accountNumber
DELETE FROM myDataTable2 WHERE accountNumber = @accountNumber
DELETE FROM myDataTable3 WHERE accountNumber = @accountNumber
//Etc.........
END TRY
BEGIN CATCH
//CATCH ERROR
END CATCH
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
SET ANSI_NULLS OFF;
SET NOCOUNT OFF;
END
問題は、場合によっては、テーブルに10,000行を超える可能性があり、手順に最大3〜5分かかる可能性があることです。この期間中、データベース上の他のすべての接続が抑制され、次のようなタイムアウトエラーが発生します。
System.Data.SqlClient.SqlException(0x80131904):タイムアウトが期限切れになりました。操作が完了する前にタイムアウト期間が経過したか、サーバーが応答していません。
パフォーマンスを向上させるために行うことができる一般的な変更はありますか?データベーススキーマの設計に関連する不明な点がたくさんあることを感謝しますが、一般的なベストプラクティスのアドバイスを歓迎します。影響を最小限に抑えるために、このタスクを早い時間に実行するようにスケジュールすることを考えましたが、このタスクが完了するまでユーザーはアカウントへのアクセスを取り戻すことができないため、これは理想からはほど遠いものです。
追加情報:
- SQL Server2008R2標準
- すべてのテーブルにはクラスター化インデックスがあります
- 関連するテーブルの削除コマンドにトリガーが関連付けられていません
- 外部キー参照は多くのテーブルに存在しますが、削除順序がこれを説明しています。
編集:16:52 GMT
削除手順は約20のテーブルに影響します。最大のものは約500万件のレコードがあります。他には200,000がなく、1000〜2000のレコードしか含まれていないものもあります。