Re: Metodo mas rapido que Join ???

From: Gabriel Hermes Colina Zambra <hermeszambra(at)yahoo(dot)com>
To: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
Cc: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: Metodo mas rapido que Join ???
Date: 2007-12-22 01:26:11
Message-ID: 154236.62111.qm@web63713.mail.re1.yahoo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda


--- Alvaro Herrera <alvherre(at)commandprompt(dot)com>
escribió:

> Gabriel Hermes Colina Zambra escribió:
> >
> > --- Alvaro Herrera <alvherre(at)commandprompt(dot)com>
> > escribió:
> >
> > > Puedes mandar los explain analyze de ambas
> formas?
>
> > Del primer ejemplo si por que este demora muy poco
> > menos, algo asi como de 1.x a 0.9 ms de diferencia
> >
> > En el segundo ejemplo siempre aborte antes de que
> me
> > arrojara el resultado.
>
> Seguramente sería suficiente con mandar el EXPLAIN
> ANALYZE del que se
> tarda poco, y el EXPLAIN (sin analyze) del otro.
>
> --
> Alvaro Herrera
> http://www.CommandPrompt.com/
> PostgreSQL Replication, Consulting, Custom
> Development, 24x7 support
> --
> TIP 1: para suscribirte y desuscribirte, visita
> http://archives.postgresql.org/pgsql-es-ayuda
>
Alvaro, desde ya gracias por tu preocupacion y la
pauta que me diste sobre que el join deberia ser igual
me dio a suponer que no estaba formulado de la mejor
manera el join, aunque en sqlserver y access esta
resuelto con esa formulacion en tiempos aceptables,
reformule el join para que trabajara directo de las
tablas en las que trabaja el otro metodo y la verdad
quede impresionado de la mejora.

Voy a presentar los tres casos en este mail para que
algo que di por supuesto no le pase a otros en
PostgreSQL y sirva documentar esto, aunque admito que
la forma del join primario era muy rebuscada puesto
que partia de views ya establecidos y en postgresql
quiza sea la causa, lo presento por que quiza haya una
pisada que se me escapa y termino desechando el
tercero mas por ignorante que por razones firmes.

El ultimo es el caso 3 en que se tarde del cual solo
voy hacer un explain.

Y el 2 con el join resuelto.

El primer caso es el caso sin Join

Caso 1



QUERY PLAN


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=1124.28..1142.17 rows=1 width=119)
(actual time=3282.604..3894.373 rows=1389 loops=1)
-> Nested Loop (cost=1124.28..1141.88 rows=1
width=124) (actual time=3282.582..3863.924 rows=1754
loops=1)
Join Filter: (csituacion04.ultimo =
track.trabajos_realizados.fecha)
-> Nested Loop (cost=1124.28..1133.58
rows=1 width=139) (actual time=3282.298..3562.269
rows=1380 loops=1)
-> Nested Loop (cost=1124.28..1132.89
rows=1 width=100) (actual time=3282.271..3541.372
rows=1380 loops=1)
-> Nested Loop
(cost=1124.28..1132.61 rows=1 width=53) (actual
time=3282.237..3516.579 rows=1380 loops=1)
Join Filter:
(track.trabajos_realizados.fecha >=
csituacion04.ultimo)
-> HashAggregate
(cost=1124.28..1124.30 rows=1 width=24) (actual
time=3281.839..3285.776 rows=1117 loops=1)
-> Nested Loop
(cost=33.27..1124.27 rows=1 width=24) (actual
time=0.879..3136.504 rows=33950 loops=1)
-> Nested Loop
(cost=33.27..1123.95 rows=1 width=28) (actual
time=0.833..2532.927 rows=33950 loops=1)
->
Nested Loop (cost=33.27..1123.63 rows=1 width=28)
(actual time=0.787..1932.345 rows=33950 loops=1)
->
Nested Loop (cost=33.27..1123.34 rows=1 width=24)
(actual time=0.738..1295.976 rows=33950 loops=1)

Join Filter:
((track.tipo_servicios.id_servicios)::text =
(track.trabajos_realizados.id_servicio)::text)

-> Nested Loop (cost=0.00..2.41 rows=1 width=12)
(actual time=0.097..0.152 rows=4 loops=1)

-> Seq Scan on categoria_servicio
(cost=0.00..1.04 rows=1 width=4) (actual
time=0.033..0.038 rows=1 loops=1)

Filter: (id_categoria = 1)

-> Seq Scan on tipo_servicios
(cost=0.00..1.36 rows=1 width=12) (actual
time=0.035..0.068 rows=4 loops=1)

Filter: (1 = id_categoria)

-> Hash Join (cost=33.27..1118.12 rows=225
width=29) (actual time=0.071..237.724 rows=44965
loops=4)

Hash Cond:
(track.trabajos_realizados.numero_aviso =
avisos_categoria.ves)

-> Seq Scan on trabajos_realizados
(cost=0.00..913.89 rows=44989 width=29) (actual
time=0.028..68.582 rows=44989 loops=4)

-> Hash (cost=33.26..33.26 rows=1 width=8)
(actual time=0.113..0.113 rows=1 loops=1)

-> Hash Join (cost=1.09..33.26 rows=1
width=8) (actual time=0.096..0.103 rows=1 loops=1)

Hash Cond:
(avisos_categoria.id_avisos =
mensajes_avisos.id_avisos)

-> Seq Scan on avisos_categoria
(cost=0.00..32.13 rows=9 width=12) (actual
time=0.016..0.020 rows=1 loops=1)

Filter: (1 = id_categoria)

-> Hash (cost=1.04..1.04 rows=4
width=4) (actual time=0.046..0.046 rows=4 loops=1)

-> Seq Scan on
mensajes_avisos (cost=0.00..1.04 rows=4 width=4)
(actual time=0.011..0.022 rows=4 loops=1)
->
Index Scan using sectores_pkey on sectores
(cost=0.00..0.27 rows=1 width=8) (actual
time=0.009..0.010 rows=1 loops=33950)

Index Cond: (sectores.id_sector =
track.trabajos_realizados.id_sector)
-> Index
Scan using locales_pkey on locales (cost=0.00..0.31
rows=1 width=8) (actual time=0.008..0.009 rows=1
loops=33950)

Index Cond: (locales.id_local = sectores.id_local)
-> Index Scan
using clientes_pkey on clientes (cost=0.00..0.31
rows=1 width=4) (actual time=0.007..0.010 rows=1
loops=33950)
Index
Cond: (clientes.id_cliente = locales.id_cliente)
-> Index Scan using
trabajos_realizados_idx1 on trabajos_realizados
(cost=0.00..8.28 rows=1 width=29) (actual
time=0.022..0.133 rows=40 loops=1117)
Index Cond:
((track.trabajos_realizados.id_cliente =
csituacion04.id_cliente) AND
(track.trabajos_realizados.id_local =
csituacion04.id_local) AND
(track.trabajos_realizados.id_sector =
csituacion04.id_sector))
-> Index Scan using
tipo_servicio_idx on tipo_servicios (cost=0.00..0.27
rows=1 width=55) (actual time=0.008..0.009 rows=1
loops=1380)
Index Cond:
((track.trabajos_realizados.id_servicio)::text =
(track.tipo_servicios.id_servicios)::text)
-> Index Scan using
categoria_servicio_pkey on categoria_servicio
(cost=0.00..0.68 rows=1 width=47) (actual
time=0.005..0.007 rows=1 loops=1380)
Index Cond:
(track.categoria_servicio.id_categoria =
track.tipo_servicios.id_categoria)
-> Index Scan using trabajos_realizados_idx1
on trabajos_realizados (cost=0.00..8.28 rows=1
width=25) (actual time=0.018..0.137 rows=48
loops=1380)
Index Cond: ((csituacion04.id_cliente =
track.trabajos_realizados.id_cliente) AND
(csituacion04.id_local =
track.trabajos_realizados.id_local) AND
(csituacion04.id_sector =
track.trabajos_realizados.id_sector))
-> Index Scan using tipo_servicio_idx on
tipo_servicios (cost=0.00..0.27 rows=1 width=8)
(actual time=0.008..0.010 rows=1 loops=1754)
Index Cond:
(((track.tipo_servicios.id_servicios)::text =
(track.trabajos_realizados.id_servicio)::text) AND
(track.tipo_servicios.id_categoria = 1))
Total runtime: 3897.717 ms
(45 filas)

Caso 2 Explain de la consulta que demora, se basa en
otras consultas


QUERY
PLAN



--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=1162.90..2258.20 rows=1 width=36)
Join Filter: ((track.sectores.id_sector =
csituacion04.id_sector) AND
(track.trabajos_realizados.id_cliente =
csituacion04.id_cliente) AND
(track.trabajos_realizados.id_local =
csituacion04.id_local) AND
((track.trabajos_realizados.fecha >
csituacion04.ultimo) OR
((track.trabajos_realizados.fecha =
csituacion04.ultimo) AND
(track.trabajos_realizados.id_trabajo >=
track.trabajos_realizados.id_trabajo))))
-> Nested Loop (cost=38.61..1125.29 rows=1
width=40)
-> Nested Loop (cost=38.61..1124.97 rows=1
width=44)
-> Nested Loop (cost=38.61..1124.64
rows=1 width=44)
-> Hash Join
(cost=38.61..1124.36 rows=1 width=36)
Hash Cond:
((track.avisos_categoria.id_categoria =
track.tipo_servicios.id_categoria) AND
((track.trabajos_realizados.id_servicio)::text =
(track.tipo_servicios.id_servicios)::text))
-> Hash Join
(cost=36.89..1121.74 rows=118 width=37)
Hash Cond:
(track.trabajos_realizados.numero_aviso =
track.avisos_categoria.ves)
-> Seq Scan on
trabajos_realizados (cost=0.00..913.89 rows=44989
width=33)
-> Hash
(cost=36.88..36.88 rows=1 width=12)
-> Hash Join
(cost=2.16..36.88 rows=1 width=12)
Hash
Cond: (track.avisos_categoria.id_avisos =
track.mensajes_avisos.id_avisos)
-> Hash
Join (cost=1.07..35.68 rows=27 width=16)

Hash Cond: (track.avisos_categoria.id_categoria =
track.categoria_servicio.id_categoria)
->
Seq Scan on avisos_categoria (cost=0.00..27.70
rows=1770 width=12)
->
Hash (cost=1.03..1.03 rows=3 width=4)

-> Seq Scan on categoria_servicio (cost=0.00..1.03
rows=3 width=4)
-> Hash
(cost=1.04..1.04 rows=4 width=4)
->
Seq Scan on mensajes_avisos (cost=0.00..1.04 rows=4
width=4)
-> Hash (cost=1.29..1.29
rows=29 width=12)
-> Seq Scan on
tipo_servicios (cost=0.00..1.29 rows=29 width=12)
-> Index Scan using
sectores_pkey on sectores (cost=0.00..0.27 rows=1
width=8)
Index Cond:
(track.sectores.id_sector =
track.trabajos_realizados.id_sector)
-> Index Scan using locales_pkey on
locales (cost=0.00..0.31 rows=1 width=8)
Index Cond:
(track.locales.id_local = track.sectores.id_local)
-> Index Scan using clientes_pkey on
clientes (cost=0.00..0.31 rows=1 width=4)
Index Cond: (track.clientes.id_cliente
= track.locales.id_cliente)
-> Nested Loop (cost=1124.28..1132.89 rows=1
width=36)
-> Nested Loop (cost=1124.28..1132.61
rows=1 width=41)
Join Filter: (csituacion04.ultimo =
track.trabajos_realizados.fecha)
-> HashAggregate
(cost=1124.28..1124.30 rows=1 width=24)
-> Nested Loop
(cost=33.27..1124.27 rows=1 width=24)
-> Nested Loop
(cost=33.27..1123.95 rows=1 width=28)
-> Nested Loop
(cost=33.27..1123.63 rows=1 width=28)
-> Nested Loop
(cost=33.27..1123.34 rows=1 width=24)
Join
Filter: ((track.tipo_servicios.id_servicios)::text =
(track.trabajos_realizados.id_servicio)::text)
->
Nested Loop (cost=0.00..2.41 rows=1 width=12)
->
Seq Scan on categoria_servicio (cost=0.00..1.04
rows=1 width=4)

Filter: (id_categoria = 1)
->
Seq Scan on tipo_servicios (cost=0.00..1.36 rows=1
width=12)

Filter: (1 = id_categoria)
-> Hash
Join (cost=33.27..1118.12 rows=225 width=29)

Hash Cond: (track.trabajos_realizados.numero_aviso =
track.avisos_categoria.ves)
->
Seq Scan on trabajos_realizados (cost=0.00..913.89
rows=44989 width=29)
->
Hash (cost=33.26..33.26 rows=1 width=8)

-> Hash Join (cost=1.09..33.26 rows=1 width=8)

Hash Cond: (track.avisos_categoria.id_avisos =
track.mensajes_avisos.id_avisos)

-> Seq Scan on avisos_categoria
(cost=0.00..32.13 rows=9 width=12)

Filter: (1 = id_categoria)

-> Hash (cost=1.04..1.04 rows=4 width=4)

-> Seq Scan on mensajes_avisos
(cost=0.00..1.04 rows=4 width=4)
-> Index Scan
using sectores_pkey on sectores (cost=0.00..0.27
rows=1 width=8)
Index
Cond: (track.sectores.id_sector =
track.trabajos_realizados.id_sector)
-> Index Scan using
locales_pkey on locales (cost=0.00..0.31 rows=1
width=8)
Index Cond:
(track.locales.id_local = track.sectores.id_local)
-> Index Scan using
clientes_pkey on clientes (cost=0.00..0.31 rows=1
width=4)
Index Cond:
(track.clientes.id_cliente = track.locales.id_cliente)
-> Index Scan using
trabajos_realizados_idx1 on trabajos_realizados
(cost=0.00..8.28 rows=1 width=29)
Index Cond:
((csituacion04.id_cliente =
track.trabajos_realizados.id_cliente) AND
(csituacion04.id_local =
track.trabajos_realizados.id_local) AND
(csituacion04.id_sector =
track.trabajos_realizados.id_sector))
-> Index Scan using tipo_servicio_idx on
tipo_servicios (cost=0.00..0.27 rows=1 width=8)
Index Cond:
(((track.tipo_servicios.id_servicios)::text =
(track.trabajos_realizados.id_servicio)::text) AND
(track.tipo_servicios.id_categoria = 1))
(62 filas)

Caso 3 replanteo del join con resultado positivo.



QUERY PLAN


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=1124.28..1142.17 rows=1 width=119)
(actual time=3281.361..3890.260 rows=1389 loops=1)
-> Nested Loop (cost=1124.28..1141.88 rows=1
width=124) (actual time=3281.339..3859.945 rows=1754
loops=1)
Join Filter: (csituacion04.ultimo =
track.trabajos_realizados.fecha)
-> Nested Loop (cost=1124.28..1133.58
rows=1 width=139) (actual time=3281.052..3558.501
rows=1380 loops=1)
-> Nested Loop (cost=1124.28..1132.89
rows=1 width=100) (actual time=3281.032..3537.152
rows=1380 loops=1)
-> Nested Loop
(cost=1124.28..1132.61 rows=1 width=53) (actual
time=3281.007..3513.331 rows=1380 loops=1)
Join Filter:
(track.trabajos_realizados.fecha >=
csituacion04.ultimo)
-> HashAggregate
(cost=1124.28..1124.30 rows=1 width=24) (actual
time=3280.629..3284.566 rows=1117 loops=1)
-> Nested Loop
(cost=33.27..1124.27 rows=1 width=24) (actual
time=0.813..3126.573 rows=33950 loops=1)
-> Nested Loop
(cost=33.27..1123.95 rows=1 width=28) (actual
time=0.786..2527.649 rows=33950 loops=1)
->
Nested Loop (cost=33.27..1123.63 rows=1 width=28)
(actual time=0.759..1932.193 rows=33950 loops=1)
->
Nested Loop (cost=33.27..1123.34 rows=1 width=24)
(actual time=0.720..1299.903 rows=33950 loops=1)

Join Filter:
((track.tipo_servicios.id_servicios)::text =
(track.trabajos_realizados.id_servicio)::text)

-> Nested Loop (cost=0.00..2.41 rows=1 width=12)
(actual time=0.081..0.137 rows=4 loops=1)

-> Seq Scan on categoria_servicio
(cost=0.00..1.04 rows=1 width=4) (actual
time=0.027..0.032 rows=1 loops=1)

Filter: (id_categoria = 1)

-> Seq Scan on tipo_servicios
(cost=0.00..1.36 rows=1 width=12) (actual
time=0.029..0.063 rows=4 loops=1)

Filter: (1 = id_categoria)

-> Hash Join (cost=33.27..1118.12 rows=225
width=29) (actual time=0.070..238.151 rows=44965
loops=4)

Hash Cond:
(track.trabajos_realizados.numero_aviso =
avisos_categoria.ves)

-> Seq Scan on trabajos_realizados
(cost=0.00..913.89 rows=44989 width=29) (actual
time=0.026..68.372 rows=44989 loops=4)

-> Hash (cost=33.26..33.26 rows=1 width=8)
(actual time=0.108..0.108 rows=1 loops=1)

-> Hash Join (cost=1.09..33.26 rows=1
width=8) (actual time=0.094..0.101 rows=1 loops=1)

Hash Cond:
(avisos_categoria.id_avisos =
mensajes_avisos.id_avisos)

-> Seq Scan on avisos_categoria
(cost=0.00..32.13 rows=9 width=12) (actual
time=0.013..0.016 rows=1 loops=1)

Filter: (1 = id_categoria)

-> Hash (cost=1.04..1.04 rows=4
width=4) (actual time=0.043..0.043 rows=4 loops=1)

-> Seq Scan on
mensajes_avisos (cost=0.00..1.04 rows=4 width=4)
(actual time=0.009..0.019 rows=4 loops=1)
->
Index Scan using sectores_pkey on sectores
(cost=0.00..0.27 rows=1 width=8) (actual
time=0.009..0.010 rows=1 loops=33950)

Index Cond: (sectores.id_sector =
track.trabajos_realizados.id_sector)
-> Index
Scan using locales_pkey on locales (cost=0.00..0.31
rows=1 width=8) (actual time=0.008..0.009 rows=1
loops=33950)

Index Cond: (locales.id_local = sectores.id_local)
-> Index Scan
using clientes_pkey on clientes (cost=0.00..0.31
rows=1 width=4) (actual time=0.007..0.010 rows=1
loops=33950)
Index
Cond: (clientes.id_cliente = locales.id_cliente)
-> Index Scan using
trabajos_realizados_idx1 on trabajos_realizados
(cost=0.00..8.28 rows=1 width=29) (actual
time=0.021..0.132 rows=40 loops=1117)
Index Cond:
((track.trabajos_realizados.id_cliente =
csituacion04.id_cliente) AND
(track.trabajos_realizados.id_local =
csituacion04.id_local) AND
(track.trabajos_realizados.id_sector =
csituacion04.id_sector))
-> Index Scan using
tipo_servicio_idx on tipo_servicios (cost=0.00..0.27
rows=1 width=55) (actual time=0.007..0.009 rows=1
loops=1380)
Index Cond:
((track.trabajos_realizados.id_servicio)::text =
(track.tipo_servicios.id_servicios)::text)
-> Index Scan using
categoria_servicio_pkey on categoria_servicio
(cost=0.00..0.68 rows=1 width=47) (actual
time=0.005..0.007 rows=1 loops=1380)
Index Cond:
(track.categoria_servicio.id_categoria =
track.tipo_servicios.id_categoria)
-> Index Scan using trabajos_realizados_idx1
on trabajos_realizados (cost=0.00..8.28 rows=1
width=25) (actual time=0.018..0.136 rows=48
loops=1380)
Index Cond: ((csituacion04.id_cliente =
track.trabajos_realizados.id_cliente) AND
(csituacion04.id_local =
track.trabajos_realizados.id_local) AND
(csituacion04.id_sector =
track.trabajos_realizados.id_sector))
-> Index Scan using tipo_servicio_idx on
tipo_servicios (cost=0.00..0.27 rows=1 width=8)
(actual time=0.008..0.010 rows=1 loops=1754)
Index Cond:
(((track.tipo_servicios.id_servicios)::text =
(track.trabajos_realizados.id_servicio)::text) AND
(track.tipo_servicios.id_categoria = 1))
Total runtime: 3893.114 ms
(45 filas)

Bueno muchas gracias Alvaro, por que el hecho de que
tu digas esto tiene que ser igual me hace plantearme
nuevas formas de replantear las cosas

Un abrazo

____________________________________________________________________________________
¡Capacidad ilimitada de almacenamiento en tu correo!
No te preocupes más por el espacio de tu cuenta con Correo Yahoo!:
http://correo.espanol.yahoo.com/

In response to

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Oscar Cano 2007-12-22 15:55:23 Edad en años
Previous Message Alvaro Herrera 2007-12-21 23:32:31 Re: Metodo mas rapido que Join ???