web-dev-qa-db-ja.com

静的カーソルの使用に関する最適化

私は現在、静的カーソルを使用してデータのリストをクロールするベンダー提供のアプリケーションを社内でサポートしています。私は、カーソルの使用を影響なしに修正するために、できる限りベンダーに頼ってきました。このソフトウェアは、私たちの業務にとって重要です。

それまでの間、私の唯一の頼みの綱は、プレッシャーの一部を軽減する可能性のあるSQLServerを構成する方法を見つけることです。

制御できない静的カーソルは、次のようなクエリで開かれます。

SELECT {manyColumns} from {table} with (nolock)
WHERE {codeFieldName} > @param
ORDER BY {codeFieldName}
option (fast 1)

インデックスは適切に設定されており、最終的にtempdbに組み込まれる結果セットは、見た目とほぼ同じ速さで生成されます。しかし、これは醜いところです。

結果のテーブルのほとんどは使用されません。実際、通常は最初の項目のみが使用されますが、これらのテーブルは通常、数千のエントリ(数千の傾向ではないにしても)の長さです。さらに悪いことに、カーソルにアクセスしている間、ほとんどの場合、基になるデータは変更されないため、通常、静的カーソルは実際には必要ありません。さらに悪いことに、これはテーブルのサブセット全体をスキャンするために使用される手法です。これらのクエリは次のアイテムに関する情報をフェッチするためにのみ使用されているためです。カーソルを作成して使用し、先頭のエントリを読み取り、カーソルを破棄します。 、次にカーソルを作成して再度実行します...(はい、これは驚くべきことにO(n ^ 2)スキャンにつながります。)

SQLにこれらのカーソルを動的カーソルとして処理させる方法はありますか?または、データが変更されるまで静的カーソルがtempdbに完全なテーブルを生成しないようにする方法はありますか?他の解決策はありますか?

編集:現在SQL Server 2005ですが、2008/2008R2への移行は完全に問題外ではありません。 (私は2008年のテスト環境を持っています。)

これまでに試しました:

  • RAMディスクにtempdbをスローしました。パフォーマンスは向上しません。これらのクエリ中、SQLServerはI/Oの方法であまり機能していないようで、2000以降のバージョンのSQLの方がメモリが優れています。 。tempdb管理。(RAMディスクオプションは2000年以降に削除されましたが、これはおそらくこの理由によるものです。)
3
Kaganar

実際にカーソルコードを変更せずに、ここで役立つと私が考えることができることは実際にはほんのわずかです。

  1. Tempdbがデータベースファイルとは異なる物理ドライブに存在することを確認してください。これにより、一時/静的行セットが小さくなることはありませんが、高速になります。

  2. CURSOR_THRESHOLD構成設定を調整します。これは注意が必要なことであり、通常はお勧めしませんが、canこの状況に大きな影響を与えます(常に正の影響があるとは限りません)。デフォルトの-1から1000のようなものに調整したいと思うでしょう。ただし、サーバーはインスタンス全体であり、他のものにも影響を与える可能性があるため、注意してください。

  3. プランガイド:これには2008+が必要だと思いますが、カーソルSELECTで機能するかどうかはnot確信しています。また、使用するのも複雑ですが、機能する場合は、最適ではないクエリプランを使用している繰り返し可能なクエリに対して驚くべきことを実行できます。

それが私が考えることができるすべてです...

2
RBarryYoung