2013/1/17 Flavio Yamil Gómez <[email protected]>

> Olá colegas,
>
> Segue abaixo exemplo de query que estou executando (Query 1). Vejam que
> ela faz um "Seq Scan" na tabela de cidades (2,6 milhões de registros) e
> demora 4000ms para executar.
>
> A QUERY 2 faz um "Index Scan" e demora 17ms para executar e é exatamente
> igual à QUERY 1, exceto o segundo join que foi alterado de:
>
>  left join vw_loc_origem_destino2 on vw_loc_origem_destino2.cd_codigo =
> com_trafego.cd_origem_carga
>
> Para:
>
>  left join vw_loc_origem_destino2 on vw_loc_origem_destino2.cd_codigo = 99
>
>

Pra mim as duas consultas são *completamente* distintas. Na primeira o
PostgreSQL tem que realizar uma junção, que, muitas vezes, é mais rápido
com seq-scan do que com index-scan.

Não é difícil entender o porquê. Pense no modelo de junção mais simples, o
banco terá que navegar em uma tabela para buscar valores iguais na outra,
ou seja, não estaria buscando somente por um único registro da tabela, mas
sim vários.



> Seguem as queries:
>
> ** QUERY 1 **
> select
>  com_oferta.cd_oferta
> from
>  com_oferta
>  left join com_trafego on com_trafego.cd_oferta = com_oferta.cd_oferta
>  left join vw_loc_origem_destino2 on vw_loc_origem_destino2.cd_codigo =
> com_trafego.cd_origem_carga
> where
>      com_oferta.nr_oferta = 42
>
> Analyze da QUERY1:
>
> "Merge Right Join  (cost=532877.64..606356.25 rows=26575 width=4)"
> "  Merge Cond: (loc_cidade.cd_cidade = com_trafego.cd_origem_carga)"
> "  ->  Unique  (cost=532873.86..572735.67 rows=2657454 width=22)"
> "        ->  Sort  (cost=532873.86..539517.49 rows=2657454 width=22)"
> "              Sort Key: loc_cidade.cd_cidade,
> ((loc_cidade.nm_cidade)::text), loc_cidade.cd_pais, loc_cidade.cd_regiao,
> (3)"
> "              ->  Append  (cost=0.00..85796.08 rows=2657454 width=22)"
> "                    ->  Seq Scan on loc_cidade  (cost=0.00..59220.51
> rows=2657451 width=22)"
> "                    ->  Seq Scan on loc_porto  (cost=0.00..1.03 rows=3
> width=226)"
> "  ->  Sort  (cost=3.78..3.79 rows=2 width=8)"
> "        Sort Key: com_trafego.cd_origem_carga"
> "        ->  Hash Left Join  (cost=2.10..3.77 rows=2 width=8)"
> "              Hash Cond: (com_oferta.cd_oferta = com_trafego.cd_oferta)"
> "              ->  Seq Scan on com_oferta  (cost=0.00..1.63 rows=2
> width=4)"
> "                    Filter: (nr_oferta = 42)"
> "              ->  Hash  (cost=1.49..1.49 rows=49 width=8)"
> "                    ->  Seq Scan on com_trafego  (cost=0.00..1.49 rows=49
> width=8)"
>
>
>
> ****** QUERY 2 *********
>
> select
>  com_oferta.cd_oferta
> from
>  com_oferta
>  left join com_trafego on com_trafego.cd_oferta = com_oferta.cd_oferta
>  left join vw_loc_origem_destino2 on vw_loc_origem_destino2.cd_codigo = 99
> where
>      com_oferta.nr_oferta = 42
>
> Analyze da QUERY 2:
>
> "Nested Loop Left Join  (cost=11.73..13.51 rows=4 width=4)"
> "  ->  Hash Left Join  (cost=2.10..3.77 rows=2 width=4)"
> "        Hash Cond: (com_oferta.cd_oferta = com_trafego.cd_oferta)"
> "        ->  Seq Scan on com_oferta  (cost=0.00..1.63 rows=2 width=4)"
> "              Filter: (nr_oferta = 42)"
> "        ->  Hash  (cost=1.49..1.49 rows=49 width=4)"
> "              ->  Seq Scan on com_trafego  (cost=0.00..1.49 rows=49
> width=4)"
> "  ->  Materialize  (cost=9.63..9.69 rows=2 width=0)"
> "        ->  Subquery Scan on vw_loc_origem_destino2  (cost=9.63..9.68
> rows=2 width=0)"
> "              ->  Unique  (cost=9.63..9.66 rows=2 width=124)"
> "                    ->  Sort  (cost=9.63..9.63 rows=2 width=124)"
> "                          Sort Key: loc_cidade.cd_cidade,
> ((loc_cidade.nm_cidade)::text), loc_cidade.cd_pais, loc_cidade.cd_regiao,
> (3)"
> "                          ->  Append  (cost=0.00..9.62 rows=2 width=124)"
> "                                ->  Index Scan using pk_cidade on
> loc_cidade  (cost=0.00..8.56 rows=1 width=22)"
> "                                      Index Cond: (cd_cidade = 99)"
> "                                ->  Seq Scan on loc_porto
>  (cost=0.00..1.04 rows=1 width=226)"
> "                                      Filter: (cd_porto = 99)"
>
>
Cara, tem como mandar com EXPLAIN ANALYZE? É bem mais fácil de identificar
problemas com o coletor de estatísticas.

Mais uma coisa, use o explain.depesz.com [1] para facilitar nossa vida, =D.

[1] http://explain.depesz.com/

Atenciosamente,
-- 
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a