Я пытаюсь решить проблему производительности моего приложения. Запрос hibernate генерирует, имеет вид:
select *
from (
select this.a, this.b, this.state, this.id
from view_user this
where this.state=:1 order by this.a asc, this.b
)
where rownum <= :2
, где
- id - это первичный ключ
- есть объединенный, уникальный индекс для (a, b, id).
- view_user имеет ~ 2 миллиона записей
- view_user выполняет дальнейшие объединения с другими таблицами
Выпуск
Вышеприведенный запрос выполняет
- быстро от SQLDeveloper
- быстро из небольшого Java-приложения в спящем режиме
- очень медленно (> 100 раз медленнее) из приложения в спящем режиме
- значения для переменных связывания 2 соответственно 30 (происхождение rownum из подкачки)
- запрос гибернации имеет «форму» выше. На самом деле в представлении есть около 20 столбцов.
Текущее состояние анализа
- план запроса показывает, что индекс используется, когда запрос поступает из SQlDeveloper или "небольшого Java-приложения".
- план запроса показывает, что полное сканирование таблицы выполняется, если запрос поступает из приложения hibernate
- Трассировка БД показывает только два различия: настройки NLS (от SQLDeveloper) и немного другое форматирование (пробелы). Все остальное вроде бы тоже самое ...
Версия
- Спящий режим: 2.1.8
- jdbc драйвер: используется ojdbc14, 5 и 6. Не имеет значения
- Oracle: 10.2 и 11. Не имеет значения
=> Я рад каждому намеку на этот вопрос. Что меня беспокоит, так это то, что трассировка БД не показала каких-либо различий ... Да, похоже, это что-то про спящий режим. Но что? Как обнаружить?
Для полноты вот запрос гибернации (из журнала):
Select * from (
select this.USER_ID as USER_ID0_, this.CLIENT_ID as CLIENT_ID0_,
this.USER_NAME as USER_NAME0_, this.USER_FIRST_NAME as USER_FIR5_0_, this.USER_REMARKS as
USER_REM6_0_, this.USER_LOGIN_ID as USER_LOG7_0_, this.USER_TITLE as USER_TITLE0_,
this.user_language_code as user_lan9_0_, this.USER_SEX as USER_SEX0_,
this.USER_BIRTH_DATE as USER_BI11_0_, this.USER_TELEPHONE as USER_TE12_0_,
this.USER_TELEFAX as USER_TE13_0_, this.USER_MOBILE as USER_MO14_0_,
this.USER_EMAIL as USER_EMAIL0_, this.USER_ADDRESSLINE1 as USER_AD16_0_,
this.USER_ADDRESSLINE2 as USER_AD17_0_, this.USER_POSTALCODE as USER_PO18_0_,
this.USER_CITY as USER_CITY0_, this.USER_COUNTRY_CD as USER_CO20_0_,
this.USER_COUNTRY_NAME as USER_CO21_0_, this.USER_STATE_ID as USER_ST24_0_,
this.USER_STATE as USER_STATE0_, this.USER_TEMP_COLL_ID as USER_TE26_0_,
this.USER_TEMP_COLL_NAME as USER_TE27_0_, this.UNIT_ID as UNIT_ID0_,
this.CLIENT_NAME as CLIENT_38_0_, this.PROFILE_EXTID as PROFILE39_0_
from VIEW_USER this
where this.USER_STATE_ID=:1 order by this.USER_NAME asc, this.USER_FIRST_NAME asc
)
where rownum <= :2
Уникальный индекс превышает user_name, user_first_name, user_id.