コンテキスト: 従来の会計システムの Web UI として機能するシステムがあります。このレガシー システムは、大きなテキスト ファイルを 1 日に数回送信するので、データベースの CONTRACT テーブルを更新できます (ファイルには新しい契約が含まれているか、既存の契約の値が更新されているだけです)。このテーブルには現在、約 200 万行と約 150 列があります。これらの更新は日中に行われ、通常は常に約 40 人のユーザーがログインしているため、これらの更新中にダウンタイムを持つことはできません。
システムのユーザーは CONTRACT テーブルを更新できませんが、CONTRACT テーブルを参照するテーブルにレコードを挿入できます (CONTRACT テーブルの ID 列への外部キー)。
CONTRACT テーブルを更新するには、まず一括挿入を使用してテキスト ファイルをステージング テーブルにロードし、次に MERGE ステートメントを使用して、10 万レコードのバッチで行を作成または更新します。そして、ここに私の問題があります-MERGEステートメントの間、READ COMMITED SNAPSHOT分離を使用しているため、ユーザーはデータを表示し続けることができますが、何も挿入できません.CONTRACTテーブルがロックされているため、トランザクションはタイムアウトします.
質問:参照テーブルへの挿入をブロックせずに、データの整合性を確保しながら、この大量の行をすばやく更新する方法を知っている人はいますか?
いくつかの回避策を考えましたが、より良い方法があることを願っています。
- 外部キーを削除します。- データの一貫性を確保したいので、これは良い解決策とは思えません。
- MERGE ステートメントのバッチ サイズを小さくして、他のトランザクションでタイムアウトが発生しないようにトランザクションが十分に高速になるようにします。- これを試してみましたが、同期プロセスが遅すぎます。上で述べたように、更新ファイルを頻繁に受け取ります。更新されたデータがすぐに利用可能になることが重要です。
- 単一の CONTRACTID 列を持つ中間テーブルを作成し、CONTRACT テーブルの代わりに他のテーブルがそのテーブルを参照するようにします。これにより、まともな整合性を維持しながら、はるかに高速に更新できます。-うまくいくと思いますが、複雑に聞こえます。
更新: 外部キーを落としてしまいました。システムはしばらく運用されており、ログに外部キー制約違反が記録されていないため、一貫性のないデータが作成されることはないと確信しています。コメントしてくれたみんなに感謝します。