7

私は非常に遅いSQLクエリを見ていました(JBoss 5.1にデプロイされたHibernateを使用するJavaアプリから発生しました)。この特定のクエリは約10,000レコードを返しましたが、それでも40秒以上かかりました。

私はデータベースでトラフィックをスニッフィングすることになり(wiresharkにはTNS用のディセクタがあります)、予期しない何かを見つけました。データがサーバーから送信されたとき、各結果行は独自のTNSパケットに含まれていました。さらに、各TNSパケットは、次のパケットがデータベースから送信される前に、クライアント(つまり、アプリサーバー)によって確認されました。10Kレコードの場合、パケットを取得して確認応答するための10Kラウンドトリップがあります。パフォーマンスへの影響は甚大です。

これはひどく非効率的です。TCPは、より大きなパケットを許可し、遅延を減らしてスループットを向上させるための多くのメカニズム(スライディングウィンドウ、遅延ACK)を備えています。ただし、この場合、独自のネゴシエーションを追加するのはTNSプロトコルです。

OracleのSQLDeveloperから同じクエリを実行すると、このパターンは表示されません。クエリは、数千回の往復なしで、約1/10の時間で完了します。

短いバージョン:Oracleのワイヤープロトコル(TNS)は、クエリ結果の行ごとに1つのTNSパケットでデータを渡すようであり、サーバーが次のパケットを送信する前に、各パケットがクライアントによって確認応答される必要があります。

これに関する情報を[ここ][1]で見つけました(「tnsnames.oraファイルのSDUおよびTDUパラメーター」のセクションまでスクロールダウンしてください)。

したがって、私の質問:TNSプロトコルがより効率的になるようにOracleドライバー(私は10.2.0.4.0を使用しています)の動作を制御することは可能ですか?繰り返しますが、これはJBossにデプロイされたかなり標準的なJ2EEアプリです。

どうもありがとう!

4

2 に答える 2

6

tnsnames.oraおよびlistener.oraのSDUおよびTDUパラメーターを調整します

現在のステートメントのバッチサイズを100に設定します。

  ((OracleStatement)stmt).setRowPrefetch (100);

ノート:

プリフェッチサイズを設定すると、アプリケーションのパフォーマンスに影響を与える可能性があります。プリフェッチサイズを大きくすると、すべてのデータを取得するために必要なラウンドトリップの数が減りますが、メモリ使用量は増えます。これは、クエリの列の数とサイズ、および返されると予想される行の数によって異なります。また、JDBCクライアントマシンのメモリとCPUの負荷にも依存します。スタンドアロンクライアントアプリケーションに最適なものは、負荷の高いアプリケーションサーバーとは異なります。ネットワーク接続の速度と遅延も考慮する必要があります接続も考慮する必要があります

Oracle Database JDBC開発者ガイドおよびリファレンスから)

ここで利用可能な接続プロパティ。

OracleUCPもご覧ください。

于 2010-10-08T20:27:25.457 に答える
3

satementオブジェクトのフェッチサイズを増やしてみてください。

デフォルトは10だと思うので、100から始めてみてください。

ステートメントstmt=connection.createStatement();
stmt.setFetchSize(100);
ResultSet rs = stmt.executeQuery( "SELECT ...");
于 2010-10-08T20:09:28.660 に答える