Любое решение для неэффективности Oracle TNS (многие круглаи, задержка) из приложения Java?

StackOverflow https://stackoverflow.com/questions/3893943

  •  28-09-2019
  •  | 
  •  

Вопрос

Я смотрел на очень медленный запрос SQL (происходящий из приложения Java с использованием Hibernate, развернутого в JBoss 5.1). Этот конкретный запрос вернул около 10 тысяч записей, но все еще занял 40 или более.

Я закончил тем, что понюхал трафик с помощью базы данных (Wireshark имеет дискуссион для TNS) и нашел что -то неожиданное. Когда данные поступали с сервера, каждая строка результатов была в своем собственном пакете TNS. Кроме того, каждый пакет TNS был признан клиентом (т. Е. Сервер приложений) до того, как следующий был отправлен из базы данных. Для 10K записей есть 10 тыс. Крунд, чтобы получить пакет и подтвердить его. Влияние на производительность огромно.

Это ужасно неэффективно. TCP позволяет большим пакетам и имеет ряд механизмов (скользящие окна, отложенные ACK) для снижения задержки и повышения пропускной способности. Однако в этом случае это протокол TNS сверху, который добавляет свои собственные переговоры.

Если я запускаю тот же запрос от разработчика SQL Oracle, я не вижу этот шаблон. Запрос завершается около 1/10 времени, без тысяч круглых поездок.

Укороченная версия: Протокол Oracle (TNS), по-видимому, передает данные в одном TNS-пакете в соответствии с строкой результирования запроса и требует, чтобы каждый пакет был признан клиентом до того, как сервер отправит следующий.

Я нашел некоторую информацию об этом [здесь] [1] (прокрутите вниз до секции на параметрах SDU и TDU в файле TNSNAMES.ORA ').

И, следовательно, мой вопрос: возможно ли контролировать поведение драйвера Oracle (я использую 10.2.0.4.0), поэтому протокол TNS более эффективен? Опять же, это довольно стандартное приложение J2EE, развернутое в jboss.

Большое спасибо!

Это было полезно?

Решение

Настроить Сду и Тду. Параметры в tnsnames.ora and alinger.ora

Чтобы установить размер партии до 100 для текущей ставки.

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

Примечание:

Установка размера предварительной выборки может повлиять на производительность приложения. Увеличение размера предварительной выборки уменьшит количество обратных поездок, необходимых для получения всех данных, но увеличит использование памяти. Это будет зависеть от количества и размера столбцов в запросе и количества строк, которые, как ожидается, будут возвращены. Это также будет зависеть от загрузки памяти и процессора клиентской машины JDBC. Оптимальный для автономного клиентского приложения будет отличаться от сильно загруженного сервера приложений. Скорость и задержка сетевого соединения также должны рассматриваться

(от Руководство по разработке и справочнику разработчика базы данных Oracle )

Доступные свойства соединения здесь.

Также посмотрите на Oracle UCP. слишком.

Другие советы

Попробуйте увеличить размер выборки для вашего объекта Sopement.

Я думаю, что по умолчанию 10 - это 10, так что вы можете попытаться начать с 100.

Statement stmt = connection.createStatement();
stmt.setFetchSize(100);
ResultSet rs = stmt.executeQuery("SELECT ...");
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top