11

SQL 2000 サーバーで (別のアプリ サーバー上の多数の Java アプリケーションから) パフォーマンスの問題を抱えているアプリ開発チームを支援しようとしているときに、SQL トレースを実行したところ、データベースへのすべての呼び出しが API でいっぱいであることがわかりました。サーバー カーソル ステートメント (sp_cursorprepexec、sp_cursorfetch、sp_cursorclose)。

一度に 128 行のデータのみを取得して、サーバー側カーソルの使用を強制するいくつかの接続文字列プロパティを指定しているようです

API カーソルの属性またはプロパティが既定値以外に設定されている場合、SQL Server の OLE DB プロバイダーおよび SQL Server ODBC ドライバーは、既定の結果セットではなく API サーバー カーソルを使用します。行をフェッチする API 関数を呼び出すたびに、サーバーへのラウンドトリップが生成され、API サーバー カーソルから行がフェッチされます。

UPDATE : 問題の接続文字列は、JDBC 接続文字列パラメーターselectMethod=cursor(上記で説明したサーバー側のカーソルを有効にする) と代替のselectMethod=direct. 彼らはselectMethod=cursor、すべてのアプリから標準の接続文字列として使用しています。

私の DBA の観点からは、これは面倒であり (無駄なジャンクでトレースが乱雑になります)、(私は推測します) アプリから SQL サーバーへの余分なラウンド トリップが多数発生し、全体的なパフォーマンスが低下します。

彼らは (約 60 の異なるアプリ接続の 1 つにすぎない) への変更をテストしたようですselectMethod=directが、いくつかの問題 (詳細は不明) が発生し、アプリケーションが壊れることを懸念しています。

だから、私の質問は次のとおりです。

  • selectMethod=cursor私が主張しようとしたように、より低いアプリケーションパフォーマンスを使用できますか? (1 秒あたりのクエリ数が既に非常に多い SQL サーバーで必要なラウンド トリップの数を増やすことにより)
  • selectMethod=JDBC 接続でのアプリケーション透過設定はありますか? これを変更すると、アプリが壊れる可能性がありますか?
  • より一般的には、いつcursorvsを使用する必要がありますdirectか?

SFにもクロスポスト

EDIT : タイトル、質問、およびタグの大幅な編集を保証する実際の技術的な詳細を受け取りました。

編集:報奨金を追加しました。また、SF の質問に報奨金を追加しました (この質問はアプリケーションの動作に焦点を当てており、SF の質問は SQL のパフォーマンスに焦点を当てています)。ありがとう!!

4

2 に答える 2

13

簡単に言えば、

  1. selectMethod=cursor
    • 理論的には、より多くのサーバー側リソースが必要ですselectMethod=direct
    • 一度に最大でバッチ サイズのレコードのみをクライアント メモリにロードするため、より予測可能なクライアント メモリ フットプリントが得られます。
  2. selectMethod=direct
    • 理論的には、必要なサーバー側のリソースはselectMethod=cursor
    • クライアント アプリケーションが結果セットを反復処理する前に、結果セット全体をクライアント メモリに読み込みます (ドライバーが非同期結果セットの取得をネイティブにサポートしている場合を除く)。これにより、次の 2 つの点でパフォーマンスが低下する可能性があります
      1. クライアント アプリケーションが、結果セットの一部のみをトラバースした後に処理を停止するように記述されている場合、大きな結果セットでパフォーマンスが低下します (directデータを取得するためのコストが既に支払われているため、実質的に破棄されます。cursor無駄があるため、せいぜいバッチサイズ- 1 行に制限されます -- 早期終了条件は、とにかく SQL で再コーディングする必要があります (例:SELECT TOPまたはウィンドウ関数) 。
      2. 潜在的なガベージ コレクションやメモリ フットプリントの増加に関連するメモリ不足の問題が原因で、大きな結果セットでパフォーマンスが低下する

要約すれば、

  • selectMethod=cursor低いアプリケーション パフォーマンスを使用できますか? -- どちらの方法でも、さまざまな理由でパフォーマンスが低下する可能性があります。特定の結果セットのサイズを超えても、cursorまだ望ましい場合があります。どちらを使用するかについては、以下を参照してください
  • selectMethod=JDBC 接続でのアプリケーション透過設定はありますか? -- 透過的ですが、メモリ使用量が大幅に増加してクライアント システム (およびそれに応じてサーバー) が占有されたり、クライアントが完全にクラッシュしたりすると、アプリが破損する可能性があります。
  • より一般的には、いつcursorvsを使用する必要がありますdirectか? -- 個人的にはcursor、潜在的に大きな結果セットや制限のない結果セットを処理するときに使用します。ラウンドトリップのオーバーヘッドは、バッチ サイズが十分に大きい場合に償却され、クライアントのメモリ フットプリントは予測可能です。予想される結果セットのサイズが、 で使用directするバッチ サイズよりも小さいことがわかっている場合cursor、または何らかの方法でバインドされている場合、またはメモリが問題にならない場合に使用します。
于 2010-09-14T04:08:03.907 に答える