JDBC для Oracle DB: подключение.getMetadata() занимает вечность — есть какие-либо подсказки, почему и как это ускорить?

#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 секунду, даже если этот режим установлен в ЛИНГВИСТИЧЕСКИЙ.