Benchmark Oracle: Binds & Commit
Para demonstração no Curso de Performance Diagnostics & Tuning, fiz um rápido Benchmark para analisarmos as consequências de uma aplicação que não é desenhada corretamente para o Oracle Database.
Fiz 4 scripts que executam 10000 Inserts de um único NUMBER sequencial em uma tabela vazia, de apenas uma coluna.
oracle@rproni-laptop:~$ ls -l *.pl
-rw-r--r-- 1 oracle oinstall 629 2010-03-22 16:49 NoCommit_NoBinds.pl
-rw-r--r-- 1 oracle oinstall 630 2010-03-22 16:48 NoCommit_WithBinds.pl
-rw-r--r-- 1 oracle oinstall 629 2010-03-22 17:12 WithCommit_NoBinds.pl
-rw-r--r-- 1 oracle oinstall 630 2010-03-22 16:49 WithCommit_WithBinds.pl
- O primeiro script é o método correto de se desenvolver uma aplicação que utiliza o Oracle Database, pois ele utiliza variáveis Binds, e só executa Commit ao término na regra de negócio.
- O segundo script utiliza variáveis Literais ao invés de Binds, mas utiliza o Commit corretamente, como o script acima.
- O terceiro script executa Commit logo após cada um dos 10000 Inserts, mas utiliza Binds corretamente.
- O quarto script é o pior caso, pois além do Commit automático, não utiliza variáveis Bind.
Abaixo, o resultado da medição do tempo de execução e uso de CPU de cada um deles. Decida qual é o melhor.
oracle@rproni-laptop:~$
time perl NoCommit_WithBinds.pl;
time perl NoCommit_NoBinds.pl;
time perl WithCommit_WithBinds.pl;
time perl WithCommit_NoBinds.pl
real 0m14.061s
user 0m3.916s
sys 0m0.908s
real 0m24.219s
user 0m3.748s
sys 0m0.972s
real 2m43.231s
user 0m5.532s
sys 0m1.172s
real 2m46.057s
user 0m4.432s
sys 0m1.132s
É interessante notar que os scripts que executam os métodos incorretos, demoram muito mais tempo, mas consumem quase o mesmo de CPU. É por isso que achamos que “o Banco está tranquilo” enquanto o TEMPO de resposta da aplicação está péssimo. O tempo é gesto em WAITs, e não em CPU.
Fala Portilho..!
Nada melhor doq fatos para demonstrar que algo esta certo ou errado..!!
Agora uma dúvida.. e quando o insert é com mais de 100 milhões de linhas, qual seria o melhor metodo?
Deixar o commit para o final e encher a área de undo ou dar commit a cada 1 milhão ou mais?
Onde a regra de negocio permite uma recarga dos dados caso o processo seja abortado inesperadamente…
Abraços..!
Regis Araujo
Grande Regis !
Em Oracle, você deve fazer o Commit quando você deve fazer o Commit, ou seja, quando sua regra de negócio permite e exige o Commit.
O UNDO deve atender sua regra de negócio, e não a arquitetura do Oracle.
No caso de INSERT de 100 milhões de linhas não haverá necessidae de leitura do UNDO para reconstrução da imagem consistente, mas no caso de um UPDATE e DELETE sim. Mas se você faz um UPDATE ou DELETE no Oracle de 100 milhões de linhas, é melhor repensar seu ?rocesso (CTAS…).
Entretanto, o maior perigo é o Commit indiscriminado, o AutoCommit. Este sim é prejudicial, para o negócio e para o Oracle.
Abraço !
Opa..
Valeu..!
Eh.. realmente o commit vai depender da regra de negocio…!!
Abraços..!
Olá Portilho, primeiramente parabéns pelo post.
Achei interessante a pergunta do Regis, como você disse, no INSERT o Oracle não terá que ler a Before Image nos segmentos de Undo. E só para acrescentar, nas instruções de INSERT o Oracle irá ter que registrar nos segmentos de Undo somente um ponteiro para cada linha, não todo o conteúdo da linha, pois se o usuário der um ROLLBACK ele usará esses ponteiros para desfazer as alterações feitas nessas linhas. Com isso é gasto muito menos espaço nos segmentos de undo quando se usa INSERT.
Portilho, tenho uma dúvida: Quando usamos CTAS o Oracle dará INSERT para popular a tabela recém criada ?
Abraço.
Oi Rodrigo. Ótimo comentário.
O CTAS faz Insert Direct Path, mas se vocÊ olhar no Trace ou no Log Miner, não verá o comando INSERT, apenas o CTAS.
Já testei ele ao invés de INSERT com APPEND PARALLEL, e não tive muito ganho. Mas o CTAS x UPDATE ou DELETE, ganha disparado. E com o NOLOGGING e PARALLEL, o ganho é maior ainda.
Abraço !
Portilho
Parabéns pelo post!
Não sei se perdi algo ao ler… mas qual a diferença (significados) entre “real”, “user” e “sys” nos resultados?
Abraço
Oi André. Obrigado !
Seguem as explicações:
– real: Tempo de relógio.
– user: Tempo de processos de usuário, o usuário oracle incluso.
– sys:Tempo do kernel do S.O., gasto por exemplo, para Switch Context.
Abraço !
Oi Portilho, obrigado mesmo pela explicação. Se tiver uma documentação disponível explicando mais como o CTAS funciona, ficaria grato.
Um abraço.
Oi Rodrigo.
A um tempo atrás coloquei dois exemplos no Blog.
E na documentação da Oracle, em Oracle Database Data Warehousing Guide, tem a explicação completa.
Abraço !
https://profissionaloracle.com.br/blogs/portilho/2008/10/20/update-lento-no-oracle/
https://profissionaloracle.com.br/blogs/portilho/2008/10/20/delete-lento-no-oracle/
http://download.oracle.com/docs/cd/B19306_01/server.102/b14223/transform.htm#sthref759
Obrigado portilho, os exemplos do blog já tinha visto, que por sinal me despertou a vontade de entender mais como o CTAS funciona.
Abraço!
Bem bons aqueles gloriosos ETLs que disparam commit linha a linha na carga.
Já vi inclusive ferramentas de mercado que trabalham assim. Coisa de alto nível…
É, muitos desenvolvedores gostam de AutoCommit, além de sempre querer fazer uma ferramenta “compatível” com outros bancos.