У нас есть веб-приложение, работающее в производственной среде, и в какой-то момент клиент пожаловался на то, насколько медленным было приложение.Как избежать этого очень тяжелого запроса, замедляющего приложение?
Когда мы проверили, что происходит с приложением и базой данных мы открываем этот «драгоценный» запрос, который в настоящее время выполняется несколько пользователей одновременно (таким образом, нанося чрезвычайно высокой нагрузкой на сервере базы данных):
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
Наше приложение не выполняет этот запрос, я считаю, что это внутренний запрос Hibernate. Я нашел мало информации о том, почему Hibernate делает этот чрезвычайно тяжелый запрос, поэтому любая помощь в том, как его избежать, очень ценится!
Информация о производственной среде: Red Hat Enterprise Linux 5.3 (Tikanga), JDK 1.5, веб-контейнер OC4J (белый сервер приложений Oracle), Oracle Database 10.1.0.4, драйвер JDBC для JDK 1.2 и 1.3, версия Hibernate 3.2.6 .ga, библиотека пула соединений C3P0 версия 0.9.1.
UPDATE: Благодаря @BalusC для claryfing, что на самом деле это Hibernate, который выполняет запрос, теперь у меня есть лучшее представление о том, что происходит. Я объясню, как мы обрабатываем сессию спящего режима (это очень рудиментарно, да, если у вас есть предложения о том, как с этим справиться лучше, они более чем приветствуются!)
У нас есть фильтр (реализует javax.servlet.Filter) что когда он запускается (метод init), он строит фабрику сеансов (судорожно это происходит только один раз). Затем каждый HttpRequest, который идет в приложение, проходит через фильтр и получает сеанс , и он начинает транзакцию. Когда процесс завершен, он возвращается через фильтр, совершает фиксацию транзакции, убивает сеанс hibernate, затем переходит к передовой странице (мы не храним сеанс hibernate в сеансе Http, потому что он никогда не работал хорошо в наших тестах).
Теперь вот часть, где я думаю, проблема. В нашей среде разработки мы развертываем наши приложения в Tomcat 5.5, и когда мы запускаем сервис, все фильтры запускаются сразу и только один раз. В производственной среде с OC4J, похоже, не работает. Мы развертываем приложение, и только когда приходит первый запрос, OC4J создает фильтры.
Это заставляет меня думать, что OC4J конкретизирует фильтры на каждый запрос (или по крайней мере несколько раз, что до сих пор не так), создавая тем самым сессионный завод по каждому запросу, которым выполняется, что% &% #% $ # query, что приводит к моей проблеме!
Теперь, это правильно? У меня есть способ настроить OC4J для того, чтобы он создавал фильтры только один раз?
Большое спасибо всем вам за то, что нашли время, чтобы ответить на это!
Вы, ребята, решили изменить приложение таким образом, чтобы результат этого запроса был кеширован? результатом этого является статическая информация, если вы не создаете инструмент управления БД. –
Также вы используете правильный диалект Hibernate и правильные драйверы JDBC Oracle? – aperkins
Я уверен, что мы используем правильный диалект, а не только драйвер (но он никогда не давал проблем раньше). И запрос не является частью приложения, это должен быть запрос на спящий режим, c3p0 или драйвер, мы не уверены, кто его выполняет. Сначала я подумал, что это водитель, так что да, мы устанавливаем последнюю. –