# 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

Responder a