非常にビジーな SQL 2000 への JDBC 接続:selectMethod=cursor vs selectMethod=direct?
-
26-09-2019 - |
質問
SQL 2000 サーバー (別々のアプリ サーバー上の多数の Java アプリケーションから) でパフォーマンスの問題を抱えているアプリ開発チームを支援しようとした過程で、SQL トレースを実行したところ、データベースへのすべての呼び出しが API でいっぱいであることがわかりました。サーバー カーソル ステートメント (sp_cursorprepexec、sp_cursorfetch、sp_cursorclose)。
サーバー側カーソルの使用を強制し、一度に 128 行のデータのみを取得する接続文字列プロパティを指定しているようです。(から http://msdn.microsoft.com/en-us/library/Aa172588)
APIカーソル属性またはプロパティがデフォルト以外のものに設定されている場合、SQL ServerのOLE DBプロバイダーとSQL Server ODBCドライバーは、デフォルトの結果セットではなくAPIサーバーカーソルを使用します。行を取得するAPI関数への各呼び出しは、サーバーに丸いトリップを生成し、APIサーバーカーソルから行を取得します。
アップデート:問題の接続文字列は JDBC 接続文字列パラメータです。 selectMethod=cursor
(これにより、上で説明したサーバー側カーソルが有効になります) と代替案 selectMethod=direct
. 。彼らは使用してきました selectMethod=cursor
すべてのアプリの標準接続文字列として。
DBA の観点から見ると、これは単なる煩わしさであり (役に立たないジャンクでトレースが乱雑になります)、(推測ですが) アプリから SQL サーバーへの余分な往復が多くなり、全体的なパフォーマンスが低下します。
彼らは(約60の異なるアプリ接続のうちの1つだけを)次のように変更するテストを行ったようです。 selectMethod=direct
しかし、いくつかの問題が発生し(詳細はわかりません)、アプリケーションが壊れるのではないかと心配しています。
そこで、私の質問は次のとおりです。
- 使用できます
selectMethod=cursor
私が主張したように、アプリケーションのパフォーマンスが低下するのでしょうか?(すでに 1 秒あたりのクエリ数が非常に多い SQL サーバーで必要なラウンドトリップ数を増やすことによって) - は
selectMethod=
JDBC 接続におけるアプリケーション透過的な設定?これを変更するとアプリが壊れる可能性がありますか? - より一般的には、いつ使用する必要がありますか
cursor
対direct
?
また SFにクロスポスト.
編集:タイトル、質問、タグの大幅な編集を保証する実際の技術的な詳細を受け取りました。
編集:報奨金を追加しました。また、SF の質問に報奨金を追加しました (この質問はアプリケーションの動作に焦点を当てており、SF の質問は SQL のパフォーマンスに焦点を当てています)。ありがとう!!
解決
簡単に言うと、
selectMethod=cursor
- 理論的には必要です より多くのサーバー側リソース よりも
selectMethod=direct
- 最大でもロードのみ バッチサイズ クライアントのメモリに一度に記録するため、クライアントのメモリ使用量がより予測可能になります
- 理論的には必要です より多くのサーバー側リソース よりも
selectMethod=direct
- 理論的には、必要なサーバー側リソースが少なくなります。
selectMethod=cursor
- クライアント アプリケーションが結果セットを反復処理する前に、結果セット全体をクライアント メモリに読み取ります (ドライバーが非同期結果セットの取得をネイティブにサポートしている場合を除く)。これ 2 つの方法でパフォーマンスが低下する可能性があります:
- 結果セットの一部のみを走査した後に処理を停止するような方法でクライアント アプリケーションが作成されている場合、結果セットが大きいとパフォーマンスが低下します (
direct
本質的には破棄するデータの取得コストをすでに支払っています。とcursor
廃棄物は最大でも次の量に制限されます バッチサイズ - 1 行 -- 早期終了条件はおそらく SQL で再コード化する必要があります。としてSELECT TOP
またはウィンドウ関数) - メモリ使用量の増加に伴う潜在的なガベージ コレクションやメモリ不足の問題により、大きな結果セットのパフォーマンスが低下する
- 結果セットの一部のみを走査した後に処理を停止するような方法でクライアント アプリケーションが作成されている場合、結果セットが大きいとパフォーマンスが低下します (
- 理論的には、必要なサーバー側リソースが少なくなります。
要約すれば、
- 使用できます
selectMethod=cursor
アプリケーションのパフォーマンスが低下しますか? -- どちらの方法でも、さまざまな理由でパフォーマンスが低下する可能性があります。特定の結果セット サイズを超えると、cursor
まだ好ましいかもしれません。どちらかをいつ使用するかについては、以下を参照してください。 - は
selectMethod=
JDBC 接続におけるアプリケーション透過的な設定? -- これは透過的ですが、メモリ使用量が大幅に増大してクライアント システム (およびそれに応じてサーバー) を占有したり、クライアントが完全にクラッシュしたりすると、アプリが中断される可能性があります。 - より一般的には、いつ使用する必要がありますか
cursor
対direct
? -- 私も個人的に使っていますcursor
潜在的に大規模な、または制限のない結果セットを扱う場合。バッチ サイズが十分に大きい場合、往復のオーバーヘッドは償却され、クライアントのメモリ フットプリントは予測可能です。私が使うdirect
期待する結果セットのサイズが、使用するバッチ サイズよりも小さいことがわかっている場合cursor
, 、または何らかの方法でバインドされている場合、またはメモリが問題ではない場合。
他のヒント
使用する selectMethod=cursor
SQL Server が使用できないようにする 並列クエリ処理, これは、たとえば次の場合にパフォーマンスに大きな影響を与える可能性があります。
- たくさんの CPU コアを持っています (持っていない人がいるでしょうか?)
- テーブルを分割してデータベースを最適化しました
- 大量の集計クエリを実行しています (
sum()
,count()
, 、など)
最後に、マイクロソフト 州 次の:
(
selectMethod=direct
) は、アプリケーションがすべての行を処理しているときに最高のパフォーマンスを提供します。
selectMethod=direct の設定によって違いが生じるかどうかを必ず試して確認してください。