Путаница с методом setFetchSize объекта Statement
Изначально я задавал этот вопрос
Я решаю это, установив fetchSize
в Integer.MIN_VALUE
но у меня есть несколько вопросов по этому поводу
- Когда я устанавливаю fetchSize в 10 или другое положительное целое число, оно не работает, после установки его в
Integer.MIN_VALUE
это работает, почему это? - Если мы устанавливаем отрицательное значение, то это дает недопустимую ошибку, но
Integer.MIN_VALUE
является-2147483648
так почему это не дает ошибок? - Эта таблица содержит 6 миллионов записей, и я закрыл
resultset
после получения 100 или 200 записей это занимает 30-35 секунд. - Решение, чтобы уменьшить время, чтобы закрыть это
resultset
,
Я хочу добавить кое-что еще здесь, я проверил это с драйвером MySQL, и он принимает Integer.MIN_VALUE
но когда я тестирую тот же код в SQL-сервере, то выдает ошибку The fetch size cannot be negative.
и если я установлю его на 10, то он работает, он также работает для Oracle.
1 ответ
Integer.MIN_VALUE используется драйвером MySQL в качестве сигнала для переключения в режим набора результатов потоковой передачи. Это не используется в качестве значения. См. Документацию в разделе "Resultset". В итоге:
По умолчанию ResultSets полностью извлекаются и сохраняются в памяти. Вы можете указать драйверу потоковую передачу результатов по одной строке за раз, установив stmt.setFetchSize(Integer.MIN_VALUE);
(в сочетании с набором результатов только для чтения и чтения).
Так что это очень специфично для драйвера MySQL Connector/J.
Что касается того, почему закрытие результирующего набора занимает много времени, это также подразумевается в той же документации: "Вы должны прочитать все строки в результирующем наборе (или закрыть его), прежде чем сможете выполнить какие-либо другие запросы для соединения, или будет выдвинуто исключение ".
Т.е. закрытие набора результатов сначала прочитает все оставшиеся строки, а затем закроет набор результатов. И поскольку чтение строк теперь выполняется построчно, это может занять много времени. Эта проблема и обходной путь / взлом также описаны в этом вопросе.
Похоже (я не проверял это) есть альтернатива потоковому результирующему набору, которая может делать то, что вы хотите (без использования предельного предложения MySQL), она включает свойство конфигурации useCursorFetch=true
и использование объясняется здесь.