Oracle Tuning – SQL: "Ah, é só um SELECT SYSDATE"

cncpt070

Em Oracle Tuning – SQL, menos é mais. Menos tarefas para o Oracle é mais velocidade.

Este script simples faz em LOOP um INSERT de uma única linha.

[ricardo@Melquior OTSQL]$ cat SemPLSQL.pl
use strict;
use warnings;
use DBD::Oracle qw(:ora_session_modes);

### Conexão com o banco de dados.
my $quantidade = $ARGV[0];
my $oracle_hostname = 'localhost';
my $oracle_database = 'ORCL';
my $oracle_username = 'SCOTT';
my $oracle_password = 'TIGER';
my $oracle_dbh = DBI->connect("dbi:Oracle:host=$oracle_hostname;sid=$oracle_database", $oracle_username, $oracle_password, {RaiseError => 1, AutoCommit => 0});

### LOOP para teste de carga.
for (my $numero = 1; $numero < $quantidade; $numero++)
	{
	my $oracle_sql = "INSERT INTO T315 (C1) VALUES (?)";
	my $oracle_sth = $oracle_dbh->prepare($oracle_sql) or die $DBI::errstr;
 	$oracle_sth->execute($numero) or die $DBI::errstr;
	}

$oracle_dbh->disconnect;
exit;

[ricardo@Melquior OTSQL]$

Este outro script é quase igual, mas antes do INSERT, é acionado o Engine de PL/SQL, apenas para declarar uma variável, colocar o conteúdo de SYSDATE nela, e não fazer mais nada.

[ricardo@Melquior OTSQL]$ cat ComPLSQL.pl
use strict;
use warnings;
use DBD::Oracle qw(:ora_session_modes);

### Conexão com o banco de dados.
my $quantidade = $ARGV[0];
my $oracle_hostname = 'localhost';
my $oracle_database = 'ORCL';
my $oracle_username = 'SCOTT';
my $oracle_password = 'TIGER';
my $oracle_dbh = DBI->connect("dbi:Oracle:host=$oracle_hostname;sid=$oracle_database", $oracle_username, $oracle_password, {RaiseError => 1, AutoCommit => 0});

### LOOP para teste de carga.
for (my $numero = 1; $numero < $quantidade; $numero++)
	{
        my $oracle_sql_01 = "DECLARE vDIA DATE; BEGIN SELECT SYSDATE INTO vDIA FROM DUAL; END;";
        my $oracle_sth_01 = $oracle_dbh->prepare($oracle_sql_01) or die $DBI::errstr;
        $oracle_sth_01->execute() or die $DBI::errstr;
	my $oracle_sql_02 = "INSERT INTO T315 (C1) VALUES (?)";
	my $oracle_sth_02 = $oracle_dbh->prepare($oracle_sql_02) or die $DBI::errstr;
 	$oracle_sth_02->execute($numero) or die $DBI::errstr;
	}

$oracle_dbh->disconnect;
exit;

[ricardo@Melquior OTSQL]$

Vamos medir (3 vezes, para garantir) o tempo necessário para executar este LOOP 10.000 vezes.

[ricardo@Melquior OTSQL]$ time perl SemPLSQL.pl 10000

real	0m5.497s
user	0m2.214s
sys	0m0.694s
[ricardo@Melquior OTSQL]$ time perl SemPLSQL.pl 10000

real	0m6.129s
user	0m2.153s
sys	0m0.675s
[ricardo@Melquior OTSQL]$ time perl SemPLSQL.pl 10000

real	0m5.343s
user	0m2.261s
sys	0m0.645s

Agora vejam qual o impacto de uma simples chamada dessas. O tempo praticamente dobra, tanto no real (o tempo de relógio), quanto no user (o tempo do usuário oracle), quanto no sys (onde está o context switch entre os Engines SQL e PL/SQL).

[ricardo@Melquior OTSQL]$ time perl ComPLSQL.pl 10000

real	0m10.944s
user	0m3.890s
sys	0m1.421s
[ricardo@Melquior OTSQL]$ time perl ComPLSQL.pl 10000

real	0m10.560s
user	0m3.751s
sys	0m1.391s
[ricardo@Melquior OTSQL]$ time perl ComPLSQL.pl 10000

real	0m8.233s
user	0m2.574s
sys	0m1.445s
[ricardo@Melquior OTSQL]$

Portanto, considere se cada linha de código executada em seu sistema é realmente necessária.

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.