Вы находитесь на странице: 1из 3

Grupo de Usurios Java

http://www.guj.com.br)

Nem sempre use stored procedures


Artur Saccaro
Um exemplo de situao em que no utilizar uma stored procedure aumentou muito a
eficincia da aplicao

Situao inicial
A alguns dias me deparei com uma determinada situao em que precisava fazer um Select e dois
Inserts em uma base de dados Oracle para cada elemento de um ArrayList dado. Sendo esta uma
operao parecida com uma funcionalidade antiga da aplicao, decidi utilizar o mesmo mtodo: uma
Stored Procedure j presente na aplicao.
Cdigo da Stored Procedure insere
create or replace procedure insere(param1 number, param2 varchar2, param3 varchar2, param4 varchar2)
is
constante number;
begin
select resultado.nextval into results from dual;
insert into tabela1 (campo1, campo2)
values(resultado, param2);
if(param1 = 1) then
insert into tabela2(campo1, campo2)
values(param3, param4);
else
insert into tabela3 (campo1, campo2, campo3)
values(param2, param3, param4);
end if;
end insere;

Trecho de cdigo da primeira soluo implementada em Java, utilizando a Stored Procedure:


String sql = "call insere(?, ?, ?, ?)";
Connection con = ConnectionBroker.getConnection();
PreparedStatement st = con.prepareStatement(sql);
Iterator iter = arrayList.iterator()
while(iter.hasNext()){
objeto = (Objeto) iter.next();
st.setInt
(1, objeto.getPropriedade1());
st.setString(2, objeto.getProperiedade2());
st.setString(3, objeto.getProperiedade3());
st.setString(4, objeto.getProperiedade4());
st.execute();
}

A stored procedure insere faz um select cujo resultado utilizado em um insert em uma dada tabela
e um outro insert em outra tabela definida pelo primeiro parmetro da procedure insere.
O processo todo levava aproximadamente UMA HORA para ser concludo quando aplicado em um
ArrayList de 5000 elementos.

Testes e a soluo
Inconformado com este resultado, preparei um teste com um script para 10000 Inserts nas mesmas
tabelas, apenas para comparao. Rodando o script diretamente na ferramenta SQLPlus da Oracle, sem
nenhuma interferncia do Java, a operao levou menos de TRS MINUTOS.
Como, infelizmente, esta stored procedure vinha como legado do sistema (o que me impedia de
modific-la), tentei uma saida menos elegante mas ainda assim mais eficiente: ignorar a procedure
Grupo de Usurios Java http://www.guj.com.br Pgina 1

Grupo de Usurios Java


http://www.guj.com.br)

E assim ficou o cdigo Java:


String sql = null;
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
int status = 0;
Iterator iter = arrayList.iterator()
while(iter.hasNext()){
objeto = (Objeto) iter.next();
// ConnectionBroker retorna uma conexo obtida usando o pool de conexes Oracle
con = ConnectionBroker.getConnection();
//Seleciona um valor da tabela 0 para definir em qual tabela fazer o insert
sql = "select status from tabela0";
st = con.prepareStatement(sql);
rs = st.executeQuery();
if(rs.next()){
status = rs.getInt(status);
}
rs.close();
st.close();
con.close();
con = ConnectionBroker.getConnection();
// Insere alguns campos na tabela 1
sql = "insert into tabela1 (campo1, campo2) values(?, ?)";
st = con.prepareStatement(sql);
st.setString(1, status);
st.setString(2, objeto.getProperiedade1());
st.execute();
st.close();
con.close();
// define qual insert fazer a partir do valor selecionado na tabela 0
if(status == 1){
con = ConnectionBroker.getConnection();
sql = "insert into tabela2 (campo1, campo2) values(?, ?)";
st = con.prepareStatement(sql);
st.setString(1, objeto.getProperiedade3());
st.setString(2, objeto.getProperiedade4());
st.executeUpdate();
st.close();
con.close();
}else{
con = ConnectionBroker.getConnection();
sql = "insert into tabela3 (campo1, campo2, campo3) values(?, ?)";
st = con.prepareStatement(sql);
st.setString(1, objeto.getProperiedade2());
st.setString(2, objeto.getProperiedade3());
st.setString(2, objeto.getProperiedade4());
st.execute();
st.close();
con.close();
}
}

Esta soluo praticamente traduz a procedure do Oracle para um mtodo Java e mesmo refazendo 3
vezes as conexes e os PreparedStatements a cada passagem do while, o processo todo levou pouco
mais de QUATRO MINUTOS para os mesmos 5000 elementos do ArrayList.
Este procedimento poderia ainda ser otimizado, uma vez que foi escrito de forma muito rpida, mas o
resultado j trouxe um ganho mais que satisfatrio para as necessidades da aplicao.

Grupo de Usurios Java http://www.guj.com.br Pgina 2

Grupo de Usurios Java


http://www.guj.com.br)

Comparativo do tempo consumido pelas operaes


70

60

50

40

30

20

10

0
Com a Stored Procedure

Com o script pelo SQL Plus

Sem a Stored Procedure

Concluso
Eu no sou contra o uso de Triggers, Stored Procedures ou Functions (embora elas possam tornar a
aplicao mais dependente do Banco de Dados), mas j vi muitos casos em que estas funcionalidades
foram utilizadas apenas por "convenincia" e, principalmente, no foram analizadas por um bom DBA. O
que eu quero dizer que as funcionalidades de um bom SGBD podem fazer a sua aplicao voar mas, se
no forem bem utilizadas, no trazem o ganho de performance esperado.
Artur Saccaro (artur@10x.com.br) desenvolvedor Java e trabalha na People Consulting desenvolvendo aplicaes
J2EE com a framework Struts e banco de dados Oracle.

Grupo de Usurios Java http://www.guj.com.br Pgina 3

Вам также может понравиться