#jdbc #oracle11g
#интерфейс jdbc #оракул11g
Вопрос:
Наше приложение при запуске проверяет наличие определенных таблиц, последовательностей и некоторых других вещей. Мы запрограммировали это прямо вперед, вот так:
... MetaData meta = connection.getMetaData(); ... ResultSet tables = meta.getTables(...); ... lt;checking for the presences of specific tablesgt; ResultSet sequences = meta.getSequences(...); ... lt;checking for the presences of specific sequencesgt; etc. ...
Хотя до сих пор первоначальный connection.getMetaData()
вызов всегда длился менее секунды, после перехода на более крупный, мощный и общий сервер БД Oracle этот вызов теперь воспроизводимо занимает более 5 минут(!). Это время относится непосредственно ко времени запуска нашего приложения, которое увеличилось более чем в четыре раза, и это, конечно, большой отказ!
Есть идеи, почему этот вызов JDBC занимает так много времени в одной системе, но не в другой? И есть ли какие-либо параметры или настройки, которые могли бы ускорить это? Обе базы данных сообщают как «Oracle Database 11g Выпуск 11.2.0.4.0 — 64-разрядная производственная версия». Оба сервера находятся в нашей интрасети, поэтому с точки зрения сети они должны быть одинаково доступны. Новый процессор и оперативная память намного мощнее и сконфигурирован в конфигурации с отказоустойчивостью (т. Е. URL — адрес подключения содержит 2 сервера на случай, если один не работает или недоступен). Старая была простой установкой на одну машину.
Что-нибудь еще, что может иметь отношение к этому или объяснить, почему этот звонок теперь занимает так много времени?
Дополнение:
Мы попытались отладить метод (но не очень далеко продвинулись). Но виновник , похоже, находится внутри DatabaseMetadata.initSequences()
, т. Е. Кажется, что извлечение последовательностей-это та часть, которая занимает так много времени на этом сервере, в то время как на другом это заняло доли секунды. Есть какая-нибудь мудрость, что может быть причиной этого?
Комментарии:
1. Какую версию драйвера Oracle JDBC вы используете?
2. ojdbc6-11.2.0.3.jar
3. Здесь нет
getSequences(...)
initSequences()
метода «илиDatabaseMetadata
«. Не могли бы вы вставить короткий рабочий пример? Имейте в виду, что операции каталога данных могут сильно отличаться в разных базах данных Oracle в зависимости от того, сколько существует схем, сколько объектов схемы и статистика.
Ответ №1:
Мы нашли виновника нашего медленного запроса метаданных! Причина в том , что во время инициализации мы устанавливаем режим сравнения LINGUISTIC
, т. е. выполняем:
alter session set nls_comp=LINGUISTIC;
При активном этом параметре извлечение последовательностей (как часть getMetadata()) занимает ~5 минут! Если мы оставим его по умолчанию (который есть alter session set nls_comp=BINARY
), то извлечение метаданных займет всего ~1 секунду!
По-видимому, этот режим сравнения приводит к полному сканированию таблицы, что приводит к такой сумасшедшей продолжительности запроса. Однако нам нужен этот режим сравнения, так как в противном случае многие наши запросы не дают совпадений (в нашем случае имена, названия компаний, адреса и т.д.), Содержащих символы с ударением.
Мы «исправили» эту проблему, переключив режим сравнения на более позднем этапе приложения после завершения проверок при запуске, которые проверяют наличие определенных таблиц и последовательностей и т.д.
Если кто-то знает подход, как ускорить создание метаданных даже при наличии режима сравнения, отличного от стандартного (например, можно ли создать специальный индекс или аналогичный)-пожалуйста, дайте мне знать!
Очевидно, что здесь должна быть какая — то дополнительная настройка, потому что, как уже упоминалось, на нашем предыдущем сервере БД извлечение метаданных заняло ~1 секунду, даже если этот режим установлен в ЛИНГВИСТИЧЕСКИЙ.