Как избежать этого очень тяжелого запроса, который замедляет приложение?

У нас есть веб-приложение, работающее в производственной среде, и в какой-то момент клиент жаловался на то, как медленный приложение добралось.

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

SELECT   NULL AS table_cat,
         o.owner AS table_schem,
         o.object_name AS table_name,
         o.object_type AS table_type,
         NULL AS remarks
FROM     all_objects o
WHERE    o.owner LIKE :1 ESCAPE :"SYS_B_0" AND
         o.object_name LIKE :2 ESCAPE :"SYS_B_1" AND
         o.object_type IN(:"SYS_B_2", :"SYS_B_3")
ORDER BY table_type, table_schem, table_name

Наше приложение не выполняет этот запрос, я полагаю, что это - Быть в спящем режиме внутреннего запроса. Я нашел мало информации о том, почему В спящем режиме, делает этот чрезвычайно тяжелый запрос, таким образом, любая справка в том, как избежать его очень, ценила!

Производственная информация о среде: Red Hat Enterprise Linux 5.3 (Tikanga), JDK 1.5, веб-контейнерный OC4J (мел Oracle Application Server), База данных Oracle 10.1.0.4, Драйвер JDBC для JDK 1.2 и 1.3, В спящем режиме версия 3.2.6.ga, версия 0.9.1 библиотеки C3P0 пула соединения.

ОБНОВЛЕНИЕ: Благодаря @BalusC для claryfing, который действительно это, в спящем режиме, который выполняет запрос, теперь у меня есть лучшая идея о том, что продолжается. Я объясню способ, которым мы обрабатываем быть в спящем режиме сессию (это является очень элементарным да, если у Вас есть предложения о том, как обработать его лучше, они - больше, чем приветствие!)

У нас есть фильтр (реализует javax.servlet. Фильтр), что, когда это - запуски (init метод) он создает фабрику сессии (supossedly это происходит только однажды). Затем каждый HttpRequest, который переходит к приложению, проходит фильтр и получает новую сессию, и он запускает транзакцию. Когда процесс, это закончено, это возвращается через фильтр, делает фиксацию транзакции, уничтожает быть в спящем режиме сессию, затем продолжите к вперед страница (мы не храним быть в спящем режиме сессию на Сеансе HTTP, потому что это никогда не работало хорошо в наших тестах).

Теперь здесь прибывает часть, где я думаю, что проблема. В нашей среде разработки мы развертываем наши приложения в Tomcat 5.5, и когда мы запускаем сервис, все фильтры запускаются сразу и только однажды. В производственной среде с OC4J, кажется, не прокладывает себе путь. Мы развертываем приложение и только когда первый запрос прибывает, OC4J инстанцирует фильтров.

Это приводит меня думать, что OC4J инстанцирует фильтров по каждому запросу (или по крайней мере многократно, который является все еще неправильным), таким образом создавая фабрику сессии по каждому запросу, который выполняет тот % и %#% $ # запрос, который приводит к моей проблеме!

Теперь, это корректно? Это - там способ для меня настроить OC4J для него для инстанцирования фильтров только однажды?

Спасибо очень всем Вам для того, чтобы занять время для ответа этого!

5
задан Pascal Thivent 9 May 2010 в 13:54
поделиться

5 ответов

Проводится ли анализ схемы sys в вашей базе данных 10g с обновленной статистикой? Вы собрали статистику по фиксированным таблицам в схеме sys. Запросы на all_objects не должны быть настолько обременительными для системы. Если вы запустите запрос через autotrace / tkprof, на что / где будут потрачены основные ресурсы.

1
ответ дан 18 December 2019 в 13:12
поделиться

Как указано в @BalusC , это запрос выполняется во время проверки схемы. Но проверка обычно выполняется раз и навсегда при создании SessionFactory (если он активирован). Вы явно вызываете следующий метод: Configuration # validateSchema (Dialect, DatabaseMetadata) ?


Это правильно? Есть ли у меня способ настроить OC4J для создания экземпляров фильтров только один раз?

Ваша реализация Open Session In View выглядит хорошо (и очень близка к предложенной в на этой странице ) . И согласно спецификации сервлета только один экземпляр на объявление в дескрипторе развертывания создается для каждой виртуальной машины Java (JVMTM) контейнера . Поскольку очень маловероятно, что это не относится к OC4J, я склонен сказать, что должно быть что-то еще.

Можете поставить лог в фильтр? Как насчет того, чтобы сделать SessionFactory статическим (в старом добром классе HibernateUtil )?

2
ответ дан 18 December 2019 в 13:12
поделиться

Я полагаю, что этот запрос исходит от драйвера Oracle JDBC для реализации запроса гибернации для получения информации об объекте базы данных через DatabaseMetaData.

Этот запрос не должен быть слишком дорогим или, по крайней мере, отсутствовать в моей удобной системе. Какое у вас количество all_objects и, что более важно, что вы видите в общем количестве строк / байтов для плана объяснения?

0
ответ дан 18 December 2019 в 13:12
поделиться

Он действительно исходит из Hibernate и, в частности, из org.hibernate.tool.hbm2ddl.TableMetadata . Он под каждым использовался для проверки схемы (сопоставление таблиц и столбцов). Очевидно, он без необходимости выполнялся при каждом порожденном запросе или сеансе, а не только один раз при запуске приложения. Вы, например, не вызываете конфигуратор Hibernate без надобности при каждом запросе или сеансе?

3
ответ дан 18 December 2019 в 13:12
поделиться

Это исходит из тестового запроса C3PO по умолчанию. Добавьте более простой запрос в свою конфигурацию. Что-то вроде, выберите «X» из двойного.

1
ответ дан 18 December 2019 в 13:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: