2014-11-19 2 views
4

Я вызываю процедуру oracle из java и в результате возвращает курсор ref. Я переместил курсор ref в ResultSet, и итерация начинается над ним.ResultSet.next() слишком медленный для курсора рефлекса оракула

String query = "{call ...(...)}"; 
CallableStatement stmt = conn.prepareCall(query,ResultSet.TYPE_FORWARD_ONLY, 
       ResultSet.CONCUR_READ_ONLY); 
stmt.setFetchSize(10000); 
. 
. 
. 
stmt.registerOutParameter(x, OracleTypes.CURSOR); 
stmt.execute(); 
Resultset rs = (ResultSet) stmt.getObject(x); 

while (rs.next()) { /** Problem occurs here **/ 
    ... 
} 

Проблема заключается в том, что ИНОГДА (не всегда) для некоторых конкретных записей метод ResultSet.next() занимает слишком много времени (например, 100 секунд). Необходимо отметить, что число возвращаемых записей не превышает 25, и тот же запрос в базе данных ведет себя нормально выполненным образом (выполняется примерно через 6 секунд).

Как я уже исследовал, я обнаружил, что в моем возвращенном курсе есть столбец, который, если удалять эту проблему, не возникает. Этот столбец на самом деле является ROWNUM(), который включен в результат.

--ORACLE Query snippet: 
OPEN result_cursor FOR 
SELECT "FirstName","LastName", r 
    FROM (SELECT ROWNUM r, * 
     ... -- query details 
     WHERE ROWNUM <= 25) 

Я даже не коснуться этого поля в ResultSet но она по-прежнему вызывает эту проблему (которая, кажется, несправедливо :(). Я попытался преобразовать его в строку в процедуре Oracle (путем конкатенации его с " '), предполагая, что преобразование типа может вызвать эту проблему, но это не имело никакого отношения к ситуации. Почему это происходит?

+0

Установка размера выборки настолько высока, что тратит память и, возможно, занимает значительное время, чтобы установить и снести структуры. Вы исключаете 'r' из окончательного списка выбора или удаляете фильтр' rownum <= 25'; по-видимому, у вас есть «порядок от», вы тоже удаляете это? –

+0

@AlexPoole: Я установил размер выборки для разных значений (10, 25, ...), и это не имело никакого значения. Я просто исключаю r из окончательного списка выбора, а тело запроса остается неизменным. Я чувствую, что курсор ref к преобразованию ResultSet вызывает эту проблему, но я не могу найти причину этого. –

+1

Возможно, у вас плохой план выполнения запроса, который включает 'r'; если вы на 10g, я задаюсь вопросом о привязке переменной peeking, особенно если она прерывистая. Можете ли вы проверить планы выполнения для обоих запросов (используя те же значения привязки)? –

ответ

1

Поле, о котором вы говорите, ROWNUM(), является изменяемым значением, поскольку могут быть вставлены строки, которые могут фактически изменить абсолютный номер строки, который затем должен быть пересчитан при выполнении операции выборки, для учета любых вставок или удалений из таблиц, возвращаемых курсором с момента последнего выбор вызова. Вызов rs.next() вызывает операцию выборки каждый раз, потому что этот столбец является изменяемым значением, даже если вы получаете остальную часть результатов довольно быстро.

Это происходит потому, что с помощью курсора курсора KEEPS THE SELECT OPEN во время навигации по ResultSet.

+0

Ну, это имеет смысл, но что может быть решением? –

+1

Попробуйте выбрать результат в таблице temp и откройте курсор в таблице temp. –

+0

Или просто верните обычный ResultSet, а не курсор. –

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