I need to improve the code where the Oracle procedure is stored from a Java program. Currently, the code is really very slow: up to 8 seconds on my development machine. On the same machine, if I directly call an SQL query that makes about the same request and returns the same data, it takes a value of less than 100 μs ...
The code creates a CallableStatement, registers one of the output parameters as an Oracle cursor, and then retrieves the cursor using the operator's getObject method and analyzes it on a 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()) { [...] }
I put some timestamps in the code to find out which part takes so long. Result: the first call to rs.next() takes up to several seconds. The result sets are average, from 10 to several thousand lines. As I said, processing similar result sets coming from a regular PreparedStatement is 10-100 μs depending on size.
Is there something wrong with the code? How to improve it? I will do direct SQL, where it is critical if I have no other solution, but I would prefer a solution that allows me not to rewrite all the procedures!
Here is the definition of the stored procedure:
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