Почему такая большая разница во времени выполнения запроса, выполняемого ADF и в SQL Developer - PullRequest
3 голосов
/ 31 августа 2010

У меня странная проблема с запросом, выполняющимся в моем веб-приложении JDeveloper ADF.Это простая форма поиска, выдающая оператор выбора в базу данных Oracle 10g.Когда запрос отправлен, среда ADF (первый) выполняет запрос, а (второй) выполняет тот же запрос, заключенный в «select count(1) from (...query...)» - цель здесь состоит в том, чтобы получить общее количество строк и отобразить «Далее».10 результатов »навигационных элементов управления.

Пока все хорошо.Проблема заключается в невероятной производительности, которую я получаю от второго запроса (с «count(1)»).Чтобы исследовать проблему, я скопировал / вставил / запустил запрос в SQL Developer и был удивлен, увидев гораздо лучший ответ.

При сравнении выполнения запросов в ADF и SQL Developer я принял все меры для обеспечения репрезентативной средыдля обоих исполнений: - только что перезапущенная база данных - то же самое для OC4J. Таким образом, я могу быть уверен, что разница не связана с кэшированием и / или буферизацией, в обоих случаях БД и сервер приложений были только что (повторно) запущены.

Трассировки, которые я выбрал для обеих сессий, иллюстрируют ситуацию:

Запрос выполняется в ADF:

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.97       0.97          0          0          0           0
Fetch        1     59.42     152.80      35129    1404149          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3     60.39     153.77      35129    1404149          0           1

Тот же запрос в SQL Developer:

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      1.02       1.16          0          0          0           0
Fetch        1      1.04       3.28       4638       4567          0           1
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      2.07       4.45       4638       4567          0           1

Заранее благодарим за любые комментарии или предложения!

Ответы [ 4 ]

3 голосов
/ 01 сентября 2010

Хорошо, я наконец нашел объяснение этому ужасному поведению. Короче говоря, ответ находится в определении (параметры настройки) моего ViewObject в JDeveloper. Мне не хватало этих двух важных параметров:

  • FetchMode = "FETCH_AS_NEEDED"
  • FetchSize = "10"

Без них происходит следующее: ADF выполняет основной запрос, связывает переменные и извлекает результаты. Затем, пытаясь оценить количество строк, он запускает тот же запрос, заключенный в "select count(1) from (my_query)", но ... (барабанная дробь) ... БЕЗ СВЯЗИ ПЕРЕМЕННЫХ !!! Меня действительно побеждает, какой смысл оценивать количество строк без учета фактических значений переменных связывания!

В любом случае, все в определении ViewObject: для получения ожидаемого поведения необходимо установить следующие параметры:

  • Все ряды в партиях: 10
  • (проверено) По мере необходимости
  • (не отмечен) Заполнить последнюю страницу строк при поиске по наборам строк

План выполнения не помог мне (он был идентичен как для ADF, так и для разработчика SQL), разница была видна только в файле трассировки, взятом с привязками.

Итак, теперь моя проблема решена - спасибо всем за советы, которые наконец привели меня к решению!

1 голос
/ 31 августа 2010

Если это тот же запрос, я могу подумать:

  • Различные настройки в ADF и SQL Developer (пробовали ли вы использовать SQL * Plus?)
  • Связывание переменных неправильного типа в медленном регистре

Но без планов выполнения или SQL трудно сказать

1 голос
/ 31 августа 2010

На протяжении многих лет я обнаружил, что «SELECT COUNT ...» часто является источником неожиданных замедлений.

Если я понимаю результаты, опубликованные выше, запрос от JDeveloper отнимает 153 секунды, но толькопримерно 4,5 секунды от разработчика SQL, и вы собираетесь использовать этот запрос, чтобы определить, должен ли отображаться элемент управления «Следующие 10 результатов».

Я не знаю, имеет ли это значение, если время выполнения составляет 4,5 секунды.или 153 секунды - даже самый лучший случай кажется довольно медленным для инициализации страницы.Предположим на мгновение, что вы можете заставить запрос отвечать за 4,5 секунды при отправке со страницы - это все еще долго, чтобы заставить пользователя сидеть и ждать, когда ему достаточно одного щелчка мыши, чтобы уйти, чтобы сделать что-то еще,За те же 4,5 секунды приложение может получить несколько данных, достаточных для загрузки страницы несколько раз.

Я думаю, что идея @ Thilo заключается в получении еще одной записи, которая необходима для заполнения страницы, чтобы определить, есть либольше доступных данных - хороший.Возможно, это может быть адаптировано к вашей ситуации?

Поделитесь и наслаждайтесь.

1 голос
/ 31 августа 2010

Запрос с подсчетом выполняется медленнее, потому что он должен прочитать все данные (для их подсчета).

Когда вы выполняете другой запрос, вы выбираете только первую страницу данных, поэтому выполнение (чтение из курсора) может остановиться после получения первых десяти результатов.

Попробуйте загрузить первую сотую страницу с первым запросом, скорее всего, она будет намного медленнее, чем первая страница.

Если выбор количества онлайн слишком дорог, обычная уловка - выбрать один элемент больше, чем вам нужно (11 в вашем случае), чтобы определить, есть ли еще данные. Вы не можете отобразить количество страниц, но, по крайней мере, кнопку «Следующая страница».

Обновление: Вы говорите, что запрос подсчета выполняется медленно только при запуске через ADF, но быстро через SQL Developer?

...