2015-04-09 3 views
2

Я использую приложение java jdbc для извлечения около 500 000 записей из БД. Используемая база данных - Oracle. Я записываю данные в файл, как только вызывается каждая строка. Поскольку для полного сбора данных требуется около часа, я пытаюсь увеличить размер выборки набора результатов. Я видел в нескольких ссылках, что, увеличивая размер выборки, нужно быть осторожным в отношении потребления памяти. Увеличивает ли размер выборки фактическое увеличение памяти кучи, используемой jvm?
Предположим, если размер выборки равен 10, а запрос программы возвращает 100 строк. Во время первой выборки набор результатов содержит 10 записей. После того, как я прочитал первые 10 записей, результаты набора получат следующее 10. Означает ли это, что после второго выбора набор данных будет содержать 20 записей? Сохраняются ли более ранние 10 записей в памяти или удаляются, когда вы выбираете новую партию? Любая помощь приветствуется.Хранит ли jdbc dataset все строки в памяти jvm

+6

Драйвер Oracle будет содержать только количество строк, определяемых fetchSiz e в памяти. Таким образом, строки из первой выборки будут освобождены, а мусор будет собран, когда вторая выборка будет выполнена. Но час на 500 000 строк кажется ужасно медленным. Вы уверены, что вы ограничены извлечением, а не самим утверждением? Запускается ли оператор в течение часа, если вы используете 'set autotrace traceonly' в SQL * Plus? Вы должны измерить время между 'executeQuery()' и первым вызовом ResultSet.next() - моя догадка заключается в том, что вы ожидаете, что Oracle подготовит ваши результаты запроса. –

+0

Да, час включает в себя выборки для всех результаты запроса. Я надеюсь, что увеличение размера выборки уменьшит общее время выборки. – Chinta

ответ

2

Это зависит. Различные драйверы могут вести себя по-разному, и разные ResultSet settings могут вести себя по-разному.

Если у вас есть CONCUR_READ_ONLY, FETCH_FORWARD, TYPE_FORWARD_ONLYResultSet, водитель почти наверняка активно хранить в памяти числа строк, которое соответствует вашему размеру выборки (конечно данных за предыдущие строки будет оставаться в памяти в течение некоторого периода времени пока не будет собран мусор). Если у вас есть TYPE_SCROLL_INSENSITIVEResultSet, с другой стороны, очень вероятно, что драйвер сохранит все данные, которые были извлечены в памяти, чтобы вы могли прокручивать назад и вперед по данным. Это не единственный возможный способ реализации этого поведения, поэтому разные драйверы (и разные версии драйверов) могут иметь разные типы поведения, но это самый простой и способ, с которым сталкиваются большинство драйверов, с которыми я сталкивался.

1

Хотя увеличение размера выборки может помочь в производительности, я также хотел бы изучить настройку размера SDU, который управляет размером пакетов на уровне sqlnet. Увеличение размера SDU может ускорить передачу данных.

Конечно, время, необходимое для извлечения этих 500 000 строк, во многом зависит от того, сколько данных вы получаете. Если потребуется час, я предполагаю, что вы извлекаете много данных и/или делаете это с удаленного клиента через WAN.

Чтобы изменить размер SDU:

Первых изменить размер SDU по умолчанию на сервере 32k (начиная с 11.2.0.3 вы можете даже использовать 64кб и до 2MB, начиная с 1) путем изменения или добавления эта линия в sqlnet.ora на сервере: DEFAULT_SDU_SIZE = 32767

Затем измените JDBC URL: JDBC: оракул: тонкий: @ (DESCRIPTION = (SDU = 32767) (HOST = ...) (PORT = ...)) (CONNECT_DATA =

Смежные вопросы