私は非常に遅い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アプリです。
どうもありがとう!