sábado, maio 12, 2007

Abstração de SGBDs - Estudo comparativo - Parte 3 - Mais sobre desempenho

Opa, to de volta!
Primeiramente, obrigado a Adriano Rivolli, Tiago Oliveira, Felipe, Marcos e alguns anônimos pelos posts nos artigos anteriores sobre o assunto. Vou insistir ainda no assunto desempenho devido à polêmica da metodologia adotada.

Minha idéia (minto, não foi minha ...) foi executar uma consulta com pequeno volume de dados que, ao repetida 250 vezes poderia gerar um resultado mais expressivo. Poderia! Como disse Marcos, além de não ser algo que algum faria na prática, pode favorecer bibliotecas que utilizem mecanismos de cache de consultas mais eficientemente. Como ele mesmo questionou, "quem faria uma coisa dessas?", talvez alguém que desenvolveu uma dessas bibliotecas, com intuitos claros de manipular o resultado em seu favor, como sugeriu Manoel Lemos no faq do Metabase.

Bom, resolvi então executar uma única consulta que trouxesse um volume maior de dados. Tá, tudo bem, ainda não é um caso real, quem iria consultar nomes de atores x titulos de filmes e exibiria 57.371 linhas, "vamo paginar essa bagaça aí né"? Mas enfim, se você está aqui é porque está interessado em saber o resultado.

Para conhecer melhor a dinâmica dos testes, leia o artigo1, o artigo2 ou baixe aqui um zipão com os scripts criados e as bibliotecas ADOdb, Metabase e Creole (DBX, PDO, DB e MDB2 foram instaladas através do pear/pecl). Ahh, para aumentar a polêmica, os testes agora foram feitos no PostgreSQL e também no MySQL.

Antes que alguém saia dizendo "tá vendo que o MySQL é mais rápido?" (ou mesmo faria isso se o resultado fosse em favor do PostgreSQL), queria deixar claro que não é o intuito desse estudo, verificar qual SGBD é o mais rápido. A questão é apenas avaliar através de qual biblioteca de abstração uma listagem de dados é feita de maneira mais eficiente. Testar em dois SGBDs torna o resultado mais autêntico. Para avaliar qual SGBD é o mais rápido, seriam necessárias diversas opções de otimização, tanto nos servidores quanto no próprio sistema operacional, o que foge totalmente da minha intenção.

Segue abaixo o script base:

$time_start = microtime(true);
$db = pg_connect("host=localhost dbname=locadora user=postgres password=postgres");

$sql = "select a.nome, f.titulo
from filmes f inner join filmesatores fa using(idfilme)
inner join atores a using (idator)
order by a.nome";
$rs = pg_query($db, $sql);
while($row = pg_fetch_row($rs)) {
echo "$row[0]: $row[1]\n";
}

$time_end = microtime(true);
$time = $time_end - $time_start;
print("\n\nTEMPO: {$time}\n");

echo pg_num_rows($rs);



Os scripts das bibliotecas estão todos no zip.

Os testes foram realizados num Sempron 2600+, 512Mb DDR400, HD 7200RPM, rodando Slackware Linux 10.2, numa partição Reiserfs, em igualdade de condições (num to roubando não, eu juro, a prova é o PostgreSQL ter ficado abaixo, quem me conhece sabe o quanto que eu "gosto" do MySQL =D).
O PHP foi chamado diretamente do shell, pra não haver envolvimento do servidor Web no resultado.

Abaixo segue o resultado médio no PostgreSQL:
Postgresql Pear DB PDO Pear MDB2 DBX ADODB Creole JDBC Creole SPL Metabase
2,48900 3,42284 2,46843 3,78125 2,72751 2,98505 3,30825 2,68212 3,37926
2,49348 3,41937 2,47007 3,78145 2,73322 2,98462 3,30672 2,67480 3,38211
2,49281 3,41792 2,47403 3,77754 2,73643 2,98938 3,30986 2,68533 3,37229
2,48918 3,41881 2,47437 3,77573 2,73429 2,98038 3,31598 2,68195 3,37205
2,49928 3,41092 2,46116 3,77751 2,72606 2,98885 3,30632 2,67427 3,37583
2,50353 3,41355 2,46660 3,77111 2,73749 2,98402 3,30085 2,68511 3,36946
2,49429 3,41590 2,46946 3,77134 2,72822 2,98827 3,29874 2,67426 3,36973
2,49729 3,40895 2,46679 3,77131 2,73000 2,98797 3,30574 2,67872 3,36731
2,49134 3,43569 2,47650 3,77919 2,72292 2,98258 3,31773 2,67193 3,36646
2,48886 3,41745 2,46946 3,77690 2,73127 2,98863 3,31203 2,68006 3,36945









24,939055 34,181396 24,696869 37,763326 27,307407 29,859731 33,082212 26,788560 33,723949
2,493905 3,418140 2,469687 3,776333 2,730741 2,985973 3,308221 2,678856 3,372395
2,503531 3,435693 2,476499 3,781448 2,737492 2,989376 3,317731 2,685334 3,382108
2,488856 3,408949 2,461159 3,771106 2,722916 2,980377 3,298736 2,671928 3,366462









0,00% 37,06% -0,97% 51,42% 9,50% 19,73% 32,65% 7,42% 35,23%
0,00% 37,06% -0,97% 51,42% 9,50% 19,73% 32,65% 7,42% 35,23%
0,00% 37,23% -1,08% 51,04% 9,35% 19,41% 32,52% 7,26% 35,09%
0,00% 36,97% -1,11% 51,52% 9,40% 19,75% 32,54% 7,36% 35,26%

Cada coluna representa os testes realizados em cada biblioteca. Foram executados e colhidos 10 valores para cada biblioteca. Abaixo, seguem respectivamente, a soma dos tempos, a média, o maior e o menor tempo. Por fim, a diferença em termos percentuais entre as bibliotecas e o PostgreSQL direto.

Na ordem:
  1. PDO
  2. PostgreSQL diretamente
  3. Creole, utilizando o método SPL
  4. ADOdb
  5. DBX
  6. Creole, utilizando o método JDBC
  7. Metabase
  8. PEAR::DB
  9. PEAR::MDB2

Destaque para o bom desempenho do PDO, que andou sempre abaixo dos tempos tomados como base e o mau desempenho, novamente, das bibliotecas do PEAR. Sistemas que tenham desempenham como requisito importante, talvez elas não sejam as melhores opções.

Abaixo, seguem os mesmos testes no MySQL:
Mysql Pear DB PDO Pear MDB2 DBX ADODB Creole JDBC Creole SPL Metabase
2,46589 3,24191 2,48229 3,35256 2,64678 2,77412 3,19877 2,93436 118,36037
2,46582 3,22849 2,46531 3,33221 2,63623 2,76856 3,18477 2,93014 118,33984
2,46999 3,22517 2,47153 3,33555 2,62988 2,76712 3,19094 2,93711 118,78771
2,46978 3,23061 2,47483 3,33502 2,63268 2,75994 3,18629 2,94175 118,64869
2,47445 3,22243 2,46748 3,33577 2,62682 2,77076 3,18985 2,93569 118,74402
2,47193 3,22906 2,46340 3,33681 2,62872 2,76505 3,19841 2,92951 118,82050
2,46494 3,22448 2,46289 3,33166 2,63245 2,76516 3,18692 2,93461 118,71466
2,46563 3,23186 2,46532 3,33192 2,63752 2,76717 3,19743 2,92785 118,62763
2,47323 3,22112 2,46734 3,32946 2,63167 2,76253 3,19038 2,93096 118,66344
2,47618 3,22932 2,46527 3,33308 2,63654 2,76481 3,19058 2,93379 118,65430









24,697852 32,284441 24,685658 33,354044 26,339296 27,665220 31,914343 29,335775 1186,361161
2,469785 3,228444 2,468566 3,335404 2,633930 2,766522 3,191434 2,933577 118,636116
2,476184 3,241906 2,482288 3,352563 2,646775 2,774116 3,198772 2,941745 118,820496
2,464941 3,221116 2,462890 3,329457 2,626821 2,759941 3,184767 2,927847 118,339844









0,00% 30,72% -0,05% 35,05% 6,65% 12,01% 29,22% 18,78% 4703,50%
0,00% 30,72% -0,05% 35,05% 6,65% 12,01% 29,22% 18,78% 4703,50%
0,00% 30,92% 0,25% 35,39% 6,89% 12,03% 29,18% 18,80% 4698,53%
0,00% 30,68% -0,08% 35,07% 6,57% 11,97% 29,20% 18,78% 4700,92%

Na ordem:
  1. PDO
  2. MySQL direto
  3. DBX
  4. ADOdb
  5. Creole SPL
  6. PEAR::DB
  7. PEAR::MDB2
  8. Metabase (?)

No geral, elas andaram mais rápido, destaque para a diferença menor em termos percentuais entre elas e a execução direta no MySQL e para um resultado estranho nos número da Metabase. Tão estranho que cheguei a procurar onde estava errando e uma melhor maneira fazer. Como não descobri, fica a deixa para quem quiser desvendar esse mistério. Interessante também o resultado melhor da DBX, que dessa vez andou sempre à frete da Creole SPL e da ADOdb. A Creole SPL também perdeu espaço para a ADOdb.

Bom, espero que dessa vez o estudo pareça mais autêntico. Peço que você teste também em outras plataformas e combinações de configuração. Abraço e até o próximo post.

Marcadores: , , , , , , , , , , ,