# select version();
version
----------------------------------------------------------------------------------------
PostgreSQL 8.3.1 on i486-pc-linux-gnu, compiled by GCC cc (GCC) 4.2.3
(Debian 4.2.3-2)
#select 1 from xmls_logs where xml_id = '534'::numeric;
?column?
----------
1
(1 registro)
Tempo: 34,068 ms
mobile_card=# select 1 from xmls_logs where xml_id = '534';
?column?
----------
1
(1 registro)
Tempo: 1,475 ms
* Bom, vamos mudar a ordem então:*
#select 1 from xmls_logs where xml_id = '534';
?column?
----------
1
(1 registro)
*Tempo: 4,725 ms*
# select 1 from xmls_logs where xml_id = '534'::numeric;
?column?
----------
1
(1 registro)
*Tempo: 35,339 ms*
Ok. Provavelmente meu servidor não possui otimizações. Mas é para
teste. É para não ter otimizações mesmo. Confesso que, para que o tempo
caísse tanto, aumentei a memória compartinhada e redizí as conexões
simultâneas. Mas o que estou tentando mostrar é o que está na documentação.
Tabela "public.xmls_logs"
Coluna | Tipo |
Modificadores
------------------+------------------------+------------------------------------------------------------
xml_id | integer | not null default
nextval('xmls_logs_xml_id_seq'::regclass)
xml_xml_in | text | not null
xml_xml_out | text |
xml_dsc_tabel | character varying(256) |
xml_int_tabel_id | integer |
xml_dat_tstam | date | not null default
('now'::text)::date
xml_tim_tstam | time without time zone | not null default (now())::time
without time zone
Índices:
"pk_xmls_logs" PRIMARY KEY, btree (xml_id)
2008/8/5 Shander Lyrio <[EMAIL PROTECTED]>
>
>
> William Leite Araújo wrote:
> > Ok. Vamos lá. Faça um teste Euler. Execute /*SELECT* * *FROM*
> > [tabela]* WHERE *[tabela].[chave] = '1.0'::NUMERIC;/
>
> Sei que era para o Euler fazer o teste mas eu não resisti. Para
> começar, que cast mais desnecessário é este que fizestes?? Não seria
> mais simples e inteligente algo como:
>
> "select * from tabela where chave = 1.0;"
>
> > De preferência em uma tabela onde hajam mais de 1000 registros. Em
> > seguida, execute a mesma consulta, mas comparando com um inteiro.
>
> Como você informa 1000 registros eu criei uma tabela com 50000 para
> que
> ficasse mais claro esta gritante diferença que o terrível numeric
> causaria nas minhas consultas. É claro que eu também me preparei com uma
> garrafa de café para passar a noite aqui esperando o retorno delas e
> também já avisei minha namorada que eu não iria para casa tão cedo.
>
> Criei a tabela assim:
>
> novo=# create table tablefoo(anytext varchar(100), valor numeric(6,3));;
> CREATE TABLE
> novo=# create index tablefoo_idx1 on tablefoo(valor);
> CREATE INDEX
>
> E gerei os 50000 valores aleatórios com um pequeno script em php
> assim:
>
> <?php
>
> include "../inc/class/Conexao.inc";
>
> $db = new Conexao();
>
> $db->beginTransaction();
> for($i = 0; $i <= 50000; $i++){
> $foo = mt_rand(0,10);
> $bar = mt_rand(0,999);
> $sql = "insert into tablefoo(anytext, valor) values('iteration $i',
> $foo.$bar);";
> $db->query($sql);
> }
> $db->commit();
>
> ?>
>
> > Oh.... é muuuuuuuuuuuuito mais lenta. Porquê? A (excelente)
> > documentação explica:
>
> Para verificar os tempos de resposta eu ativei o timing
>
> novo=# \timing
> Timing is on.
>
> Avisei a todos no meu icq e gtalk que eu ficaria off por cerca de
> 20h
> para alguns testes de performance na minha máquina.
>
> novo=# select * from tablefoo where valor = 1.345;
> anytext | valor
> -----------------+-------
> iteration 9094 | 1.345
> iteration 10389 | 1.345
> iteration 42065 | 1.345
> (3 rows)
>
> Time: 0.470 ms
> novo=# select * from tablefoo where valor = '1.345'::numeric;
> anytext | valor
> -----------------+-------
> iteration 9094 | 1.345
> iteration 10389 | 1.345
> iteration 42065 | 1.345
> (3 rows)
>
> Time: 0.477 ms
> novo=#
>
> Realmente seu casting deixou minha consulta 7 milhonésimos de
> segundo
> mais lenta. Vamos ver casting para float para ter certeza que ele é
> lento, parece que não vai dar tempo nem para tomar um café, quanto mais
> a garrafa que eu preparei:
>
> novo=# select * from tablefoo where valor = '1.345'::float;
> anytext | valor
> -----------------+-------
> iteration 9094 | 1.345
> iteration 10389 | 1.345
> iteration 42065 | 1.345
> (3 rows)
>
> Time: 90.041 ms
>
> Agora já temos uma enorme diferença, 90 milésimos de segundo.
>
> Vamos pegar a parte inteira de todos os 50000 registros para ver se
> eu
> consigo demorar mais tempo, pelo menos até tomar uma dose de café.
>
> novo=# \o lixo.txt
> novo=# select anytext, round(valor) from tablefoo;
> Time: 90.500 ms
>
> Poxa, 90 milésimos de segundo para arredondar 50000 registros
> numéric.
> Então vamos tentar converter para o tipo varchar
>
> novo=# select anytext, valor::varchar from tablefoo;
> Time: 109.672 ms
>
> Retirar somente a parte inteira dos 50000 registros;
>
> novo=# select anytext, trunc(valor) from tablefoo;
> Time: 129.208 ms
>
> Desisto, não vou ter tempo nem para tomar um cafezinho. O PostgreSql
> insiste em tratar os 50000 registros com dados numeric em menos de um
> décimo de segundo.
>
> > Ainda sem fundamento?
>
> Sinto muito cara, mas infelizmente sim.
>
> > Para compor um único registro eram feitas em torno de 10 consultas
> > dessa forma, além das 2 consultas de auto-referência (na mesma tabela
> > haviam, eventualmente, o "pai" e a "mãe" do mesmo).
>
> Como eu disse, limitação do ambiente, da tecnologia, do seu script
> de
> migração, de falta de modelagem, de qualquer outra coisa que você sonhar
> no mundo, menos do PostGreSql. Portanto eu peço que não envie mensagens
> com afirmações infundadas e distorcidas para o grupo pois pode
> prejudicar quem está começando agora no PostGreSql.
>
> > Assim, os 378,998 registros, sem o cuidado de usar um cast para tipo
> > inteiro (primeira versão da função) demorou em torno de 20 horas. Após a
> > otimização foram menos de 2 minutos.
> >
> > Infelizmente não posso lhe mostrar os dados, mas GARANTO que, tanto
> > num 8.2 quanto num 8.3, você poderá experimentar a diferença no tempo
> > simplesmente comparando uma constante numeric com uma constante integer.
>
> Opa, isto eu não tinha tentado ainda, vamos lá;
>
> novo=# select * from tablefoo where valor = 1;
> anytext | valor
> -----------------+-------
> iteration 21263 | 1.000
> iteration 34970 | 1.000
> iteration 37109 | 1.000
> iteration 42379 | 1.000
> iteration 43073 | 1.000
> (5 rows)
>
> Time: 3.568 ms
>
>
> Poxa, 3 milesegundos comparando com inteiros! Desisto cara, você fez
> mágica com sua rotina de migração. Ja liguei para minha namorada e disse
> que agente vai poder se ver, ela pediu para te agradecer, agora ainda
> estou triste por estragar uma garrafa inteira de cafezinho. Ao menos
> tomei um agora no final.
>
> Abraço,
>
Realmente, o seu caso se testes resulta nesses valores...
William Leite Araújo
Analista de Banco de Dados - QualiConsult
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral