Мне нужно улучшить код, где хранимая процедура Oracle вызывается из Java-программы. В настоящее время код действительно очень медленный: до 8 секунд на моей машине для разработки. На той же машине, если я напрямую вызываю SQL-запрос, который выполняет примерно ту же обработку и возвращает те же данные, это занимает менее 100 мс ...
Код создает CallableStatement, регистрирует один из выходных параметров как курсор Oracle, а затем извлекает курсор с помощью метода getObject оператора и анализирует его в ResultSet:
cstmt = conn.prepareCall("{ call PKG_ESPECEW.P_ListEspece( ?, ?, ?, ?, ?, ? ) }");
cstmt.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR);
[...]
cstmt.executeQuery();
rs = (ResultSet)cstmt.getObject(4);
rs.setFetchSize(1000); //supposed to help ?
options = new HashMap<String, String>(1000);
rs.next() //added that to measure exactly the length of the first call
while(rs.next()) {
[...]
}
Я добавил несколько временных меток в код, чтобы узнать, какая часть занимает так много времени. Результат: первый вызов rs.next()
занимает несколько секунд. Наборы результатов в среднем, от 10 до нескольких тысяч строк. Как я уже говорил, обработка похожих наборов результатов, поступающих из обычного PreparedStatement, занимает 10-100 мс в зависимости от размера.
Что-то не так с кодом? Как мне улучшить это? Я сделаю прямой SQL там, где это критично, если у меня нет другого решения, но я бы предпочел решение, которое позволит мне не переписывать все процедуры!
Вот определение хранимой процедуры:
PROCEDURE P_ListEspece(P_CLT_ID IN ESPECE.ESP_CLT_ID%TYPE, -- Langue de l'utilisateur
P_ESP_GROUP_CODE IN ESPECE.ESP_CODE%TYPE,-- Code du groupe ou NULL
P_Filter IN VARCHAR2, -- Filtre de la requête
P_Cursor OUT L_CURSOR_TYPE, -- Curseur
P_RecordCount OUT NUMBER, -- Nombre d'enregistrement retourne
P_ReturnStatus OUT NUMBER); -- Code d'erreur