У меня есть хранимая процедура в Oracle 11g, которую я вызываю из программы на Java, используя тонкий драйвер базы данных Oracle и CallableStatement. Эта хранимая процедура вызывается тысячи раз в цикле по одному и тому же соединению.
Вызов callableStatement.execute()
возвращается через ‹ 200 мс для первых 10-20 вызовов, однако производительность со временем начинает ухудшаться. После 200 вызовов callableStatement.execute()
теперь занимает 600 мс и продолжает ухудшаться.
Если я периодически закрываю соединение, время выполнения возвращается к нормальному диапазону ‹ 200 мс. Явно что-то неправильно кэшируется в соединении JDBC, хотя в документации указано, что CallableStatements не кэшируются.
Выполнение той же хранимой процедуры с использованием драйвера Oracle OCI в программе на языке C не показывает снижения производительности и постоянно возвращает результат в течение ‹ 200 мс.
Кто-нибудь заметил это поведение или есть какие-либо мысли об обходном пути для Java?
Редактировать: это часть кода, которая запускается много раз; Соединение является общим, CallableStatement создается в каждом цикле. Нет улучшений, если CallableStatement кэшируется.
oracle_conn_time = System.currentTimeMillis();
OracleConnection oracle_conn = (OracleConnection) conn.getMetaData().getConnection();
oracle_conn.setStatementCacheSize(1);
oracle_conn_time = System.currentTimeMillis() - oracle_conn_time;
list_time = System.currentTimeMillis();
var_args= oracle_conn.createARRAY("ARG_LIST", args.toArray());
list_time = System.currentTimeMillis() - list_time;
sql = "{? = call perform_work(?,?,?,?)}";
prepare_time = System.currentTimeMillis();
ocs = (OracleCallableStatement) oracle_conn.prepareCall(sql);
prepare_time = System.currentTimeMillis() - prepare_time;
bind_time = System.currentTimeMillis();
ocs.registerOutParameter(1, OracleTypes.ARRAY, "RESPONSEOBJ");
ocs.setInt( 2, 77);
ocs.setInt( 3, 123456);
ocs.setArray(4, var_args);
ocs.setInt( 5, 123456789);
bind_time = System.currentTimeMillis() - bind_time;
//execute_time is the only timer that shows degradation
execute_time = System.currentTimeMillis();
ocs.execute();
execute_time = System.currentTimeMillis() - execute_time;
results_time = System.currentTimeMillis();
Array return_objs = ocs.getArray(1);
results_time = System.currentTimeMillis() - results_time;
oracle_time = System.currentTimeMillis() - oracle_time;
parse_time = System.currentTimeMillis();
Clob[] clobs = (Clob[]) return_objs.getArray();
return_objs.free();
//Removed clob management code
parse_time = System.currentTimeMillis() - parse_time;