Путаница с методом setFetchSize объекта Statement

Изначально я задавал этот вопрос

Я решаю это, установив fetchSize в Integer.MIN_VALUEно у меня есть несколько вопросов по этому поводу

  1. Когда я устанавливаю fetchSize в 10 или другое положительное целое число, оно не работает, после установки его в Integer.MIN_VALUE это работает, почему это?
  2. Если мы устанавливаем отрицательное значение, то это дает недопустимую ошибку, но Integer.MIN_VALUE является -2147483648 так почему это не дает ошибок?
  3. Эта таблица содержит 6 миллионов записей, и я закрыл resultset после получения 100 или 200 записей это занимает 30-35 секунд.
  4. Решение, чтобы уменьшить время, чтобы закрыть это 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 и использование объясняется здесь.

Другие вопросы по тегам