3

画面上でのユーザーアクションにより、約50の異なるテーブルにリアルタイムで新しいレコードが作成されるシナリオがあります。ユースケースの設計では、ユーザーの操作の結果として作成された新しいレコードが、ユーザーが変更を加えるためにすぐに必要になるようになっています。したがって、オフラインまたは作成の遅延の可能性はありません。

そうは言っても、明らかな問題は、挿入ステートメント(およびいくつかの追加の操作ステートメント)がトランザクション内にあるため、非常に長いトランザクションになることです。これは約30秒間実行され、多くの場合、タイムアウトになるか、他のクエリがブロックされます。

アトミック性にはトランザクションが必要です。トランザクションを分割し、一貫性を維持するためのより良い方法はありますか?または、現在の状況を改善する他の方法はありますか?

4

2 に答える 2

5

挿入クエリは、その時点で並行して実行されている他の(ほとんどの場合選択された)クエリを待機しています

行バージョンベースの分離レベル、別名の使用を検討する必要があります。SNAPSHOT、行バージョンベースの分離レベルでは、読み取りは書き込みをブロックせず、書き込みは読み取りをブロックしないためです。まず、READ_COMMITTED_SNAPSHOTを有効にして、次のようにテストします。

ALTER DATABASE [...] SET READ_COMMITTED_SNAPSHOT ON;

行のバージョニングによって暗示される影響とトレードオフの説明については、リンクされている記事を読むことをお勧めします。

于 2012-03-22T06:33:07.337 に答える
1

コメント交換に基づいて、挿入トランザクションと並行クエリの両方を同時に確認する必要があると思います。トランザクションの整合性を失うことなく、それらの負荷に対応する必要があります。利用可能な最適化手法は次のとおりです。

  1. 頻繁に表示されるクエリや実行速度の遅いクエリの実行プランで、大きなデータセットに対して遅い構造(ネストされたループなど)に気付いた場合はいつでもアクセスインデックスを追加します。

  2. カバーインデックスの追加。これらのインデックスには、ルックアップ列に加えて追加の列が含まれており、特定のクエリでテーブルへのアクセスをまったく回避できます。これは、テーブルが広く、カバーインデックスが狭い場合に特に効率的ですが、同じ行の異なる列でのUPDATEとSELECT間のロックの問題を回避するためにも使用できます。

  3. 非正規化。たとえば、一部のクエリを切り替えて、物理テーブルや、プライマリテーブルの更新時にトリガーが提供されるセカンダリテーブルではなく、インデックス付きビューにアクセスします。これらはコストがかかり、両刃の手法であり、実証済みのトップボトルネックを解決するためにのみ検討する必要があります。

これらの手法はいずれもパフォーマンスの点で無料ではないため、測定されたスピードアップが非常に大きい場合にのみ変更を加えてください。各ステップでパフォーマンス測定を行わずに最適化しないでください。

これは些細なことですが、完全を期すために言及しましょう。実行プランの分析中と本番環境での使用の両方で、統計を最新の状態に保ちます(、、、ANALYZE...UPDATE STATISTICSデータベースエンジンごとに)。

于 2012-03-22T09:44:00.377 に答える