Problema con consulta compleja

From: Leonardo Castillo <leonardo(dot)castillo(at)alejandria(dot)biz>
To: pgsql-es-ayuda <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Problema con consulta compleja
Date: 2013-05-03 13:52:41
Message-ID: CAEtBgKyBj2wAJnT2muZi=jcGGnE1Tbwx_hDgji6-+Yi1=T7Y1Q@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Buenos días. Acudo a esta lista con el fin de buscar orientación sobre
optimización de rendimiento sobre una consulta que se hace sobre una
aplicación que construimos y que no está dando los resultados esperados en
cuanto a consulta.

La SQL dinámica que se genera es esta:

¨select distinct
CC.acceso,CC.ext_acceso,MAX(CTT.FECHA_ISO||COALESCE(CTT.HORA_ISO_INICIO,''))

from (( (( (( ((DOCUMENT CT01
INNER JOIN CENTRAL CC ON
(CT01.ACCESO = CC.ACCESO AND CT01.EXT_ACCESO = CC.EXT_ACCESO) and
( CT01.JERARQUIA = '1' ) ))
INNER JOIN (( Ocurrencias CT02 inner join palabras p0 on
(CT02.cod_palabra = p0.cod_palabra
and p0.palabra like 'LEY%' AND p0.campo = 'DESCRIPTOR'))
INNER join ( Ocurrencias o1 inner join palabras p1 on
(o1.cod_palabra = p1.cod_palabra
and p1.palabra like 'VIVIENDAS%' AND p1.campo = 'DESCRIPTOR'))
on (CT02.acceso = o1.acceso and CT02.ext_acceso = o1.ext_acceso)
)
on (CT01.acceso=o1.acceso and CT01.ext_acceso = o1.ext_acceso)))
INNER JOIN ( Ocurrencias o2 inner join palabras p2 on
(o2.cod_palabra = p2.cod_palabra
and p2.palabra like 'MINISTERIO%' AND p2.campo = 'AUTOR'))
on (CT01.acceso=o2.acceso and CT01.ext_acceso = o2.ext_acceso)))
INNER JOIN (CODDESC CT04 INNER JOIN DESCRIPT DE04 ON
(CT04.COD_DESC = DE04.CODESC) AND DE04.TIPO = 'CN' and (
DE04.DESCRIPTOR = 'VIGENTE' AND DE04.TIPO = 'CN') ) on
(CC.acceso = CT04.acceso and CC.ext_acceso = CT04.ext_acceso ))
)
, document ctt
where (CC.nivel_reg <> 's' and CC.nivel_reg <> 'mv')
AND (CC.TIPO_LITER = 'S')
AND (CC.CODIGO IS NULL OR CC.CODIGO IN ('','U0207000000*'))

and CC.acceso = ctt.acceso
and CC.ext_acceso = ctt.ext_acceso

and CC.ext_acceso > 0
AND CC.ACCESO IN
(select distinct CC.acceso
from (( ((DOCUMENT CT01
INNER JOIN CENTRAL CC ON
(CT01.ACCESO = CC.ACCESO AND CT01.EXT_ACCESO = CC.EXT_ACCESO) and
( CT01.FECHA_ISO >= '20120101' ) ))
INNER JOIN DOCUMENT CT02 on
(CC.acceso = CT02.acceso and CC.ext_acceso = CT02.ext_acceso and (
CT02.FECHA_ISO <= '20130531' ) ))
)
, document ctt
where (CC.nivel_reg <> 's' and CC.nivel_reg <> 'mv')
AND (CC.TIPO_LITER = 'S')
AND (CC.CODIGO IS NULL OR CC.CODIGO IN ('','U0207000000*'))

and CC.acceso = ctt.acceso
and CC.ext_acceso = ctt.ext_acceso

and CC.ext_acceso = 0)
GROUP BY CC.ACCESO,CC.EXT_ACCESO

ORDER BY 3 DESC,1 DESC,2 DESC
;

Las tabla OCURRENCIAS posee más de 6 millones de registros, CENTRAL y
DOCUMENT alrededor de 500 mil.

El explain de la consulta es este:

¨"Unique (cost=11088.35..11088.36 rows=1 width=44)"
" -> Sort (cost=11088.35..11088.35 rows=1 width=44)"
" Sort Key: (max(((ctt.fecha_iso)::text ||
(COALESCE(ctt.hora_iso_inicio, ''::character varying))::text))), cc.acceso,
cc.ext_acceso"
" -> HashAggregate (cost=11088.32..11088.34 rows=1 width=44)"
" -> Nested Loop (cost=7241.03..11088.31 rows=1 width=44)"
" -> Nested Loop (cost=7241.03..11079.96 rows=1
width=137)"
" Join Filter: (((ct04.acceso)::text =
(cc.acceso)::text) AND (ct04.ext_acceso = cc.ext_acceso))"
" -> Nested Loop (cost=41.17..3478.30 rows=1
width=100)"
" -> Nested Loop (cost=41.17..3475.86
rows=8 width=108)"
" -> Hash Join (cost=41.17..3471.62
rows=1 width=80)"
" Hash Cond: (o1.cod_palabra =
p1.cod_palabra)"
" -> Nested Loop
(cost=32.84..3462.15 rows=300 width=88)"
" -> Nested Loop
(cost=32.84..3362.10 rows=23 width=60)"
" -> Nested Loop
(cost=32.84..3350.80 rows=31 width=40)"
" -> Nested
Loop (cost=32.84..3330.60 rows=54 width=20)"
" ->
Index Scan using palabra on palabras p2 (cost=0.00..8.29 rows=1 width=8)"
"
Index Cond: (((palabra)::text >= 'MINISTERIO'::text) AND ((palabra)::text <
'MINISTERIP'::text) AND ((campo)::text = 'AUTOR'::text))"
"
Filter: ((palabra)::text ~~ 'MINISTERIO%'::text)"
" ->
Bitmap Heap Scan on ocurrencias o2 (cost=32.84..3311.14 rows=893 width=28)"
"
Recheck Cond: (o2.cod_palabra = p2.cod_palabra)"
"
-> Bitmap Index Scan on pk_ocurrencias (cost=0.00..32.62 rows=893
width=0)"
"
Index Cond: (o2.cod_palabra = p2.cod_palabra)"
" -> Index
Scan using pk_central on central cc (cost=0.00..0.36 rows=1 width=20)"
" Index
Cond: (((cc.acceso)::text = (o2.acceso)::text) AND (cc.ext_acceso >
0::numeric) AND (cc.ext_acceso = o2.ext_acceso))"
"
Filter: (((cc.nivel_reg)::text <> 's'::text) AND ((cc.nivel_reg)::text <>
'mv'::text) AND ((cc.codigo IS NULL) OR ((cc.codigo)::text = ANY
('{"",U0207000000*}'::text[]))) AND ((cc.tipo_liter)::text = 'S'::text))"
" -> Index Scan
using pk_document on document ct01 (cost=0.00..0.35 rows=1 width=20)"
" Index Cond:
(((ct01.acceso)::text = (cc.acceso)::text) AND (ct01.ext_acceso =
cc.ext_acceso))"
" Filter:
(ct01.jerarquia = 1::numeric)"
" -> Index Scan using
idx_oc_accesoextacceso on ocurrencias o1 (cost=0.00..4.28 rows=5 width=28)"
" Index Cond:
((o1.ext_acceso = cc.ext_acceso) AND ((o1.acceso)::text =
(cc.acceso)::text))"
" -> Hash (cost=8.29..8.29
rows=3 width=8)"
" -> Index Scan using
palabra on palabras p1 (cost=0.00..8.29 rows=3 width=8)"
" Index Cond:
(((palabra)::text >= 'VIVIENDAS'::text) AND ((palabra)::text <
'VIVIENDAT'::text) AND ((campo)::text = 'DESCRIPTOR'::text))"
" Filter:
((palabra)::text ~~ 'VIVIENDAS%'::text)"
" -> Index Scan using
idx_oc_accesoextacceso on ocurrencias ct02 (cost=0.00..4.17 rows=5
width=28)"
" Index Cond: ((ct02.ext_acceso
= cc.ext_acceso) AND ((ct02.acceso)::text = (cc.acceso)::text))"
" -> Index Scan using pk_palabras on
palabras p0 (cost=0.00..0.29 rows=1 width=8)"
" Index Cond: (p0.cod_palabra =
ct02.cod_palabra)"
" Filter: (((p0.palabra)::text ~~
'LEY%'::text) AND ((p0.campo)::text = 'DESCRIPTOR'::text))"
" -> Hash Join (cost=7199.86..7601.56 rows=6
width=37)"
" Hash Cond: ((ct04.acceso)::text =
("ANY_subquery".acceso)::text)"
" -> Nested Loop (cost=5.19..406.83
rows=13 width=20)"
" -> Index Scan using descriptor on
descript de04 (cost=0.00..8.28 rows=1 width=8)"
" Index Cond:
((descriptor)::text = 'VIGENTE'::text)"
" Filter: ((tipo)::text =
'CN'::text)"
" -> Bitmap Heap Scan on coddesc
ct04 (cost=5.19..397.20 rows=108 width=27)"
" Recheck Cond: (ct04.cod_desc =
de04.codesc)"
" -> Bitmap Index Scan on
cod_desc (cost=0.00..5.16 rows=108 width=0)"
" Index Cond:
(ct04.cod_desc = de04.codesc)"
" -> Hash (cost=7192.18..7192.18 rows=200
width=17)"
" -> HashAggregate
(cost=7190.18..7192.18 rows=200 width=17)"
" -> Subquery Scan
"ANY_subquery" (cost=7179.20..7188.96 rows=488 width=17)"
" -> HashAggregate
(cost=7179.20..7184.08 rows=488 width=14)"
" -> Nested Loop
(cost=0.00..7177.98 rows=488 width=14)"
" -> Nested
Loop (cost=0.00..4715.96 rows=251 width=48)"
" ->
Nested Loop (cost=0.00..3238.96 rows=148 width=40)"
"
-> Index Scan using fecha_iso01 on document ct01 (cost=0.00..2183.44
rows=104 width=20)"
"
Index Cond: ((fecha_iso)::text >= '20120101'::text)"
"
Filter: (ext_acceso = 0::numeric)"
"
-> Index Scan using pk_document on document ct02 (cost=0.00..10.14 rows=1
width=20)"
"
Index Cond: (((ct02.acceso)::text = (ct01.acceso)::text) AND
(ct02.ext_acceso = 0::numeric))"
"
Filter: ((ct02.fecha_iso)::text <= '20130531'::text)"
" ->
Index Scan using pk_central on central cc (cost=0.00..9.95 rows=2
width=20)"
"
Index Cond: (((cc.acceso)::text = (ct01.acceso)::text) AND (cc.ext_acceso =
0::numeric))"
"
Filter: (((cc.nivel_reg)::text <> 's'::text) AND ((cc.nivel_reg)::text <>
'mv'::text) AND ((cc.codigo IS NULL) OR ((cc.codigo)::text = ANY
('{"",U0207000000*}'::text[]))) AND ((cc.tipo_liter)::text = 'S'::text))"
" -> Index
Scan using pk_document on document ctt (cost=0.00..9.78 rows=2 width=20)"
" Index
Cond: (((ctt.acceso)::text = (cc.acceso)::text) AND (ctt.ext_acceso =
0::numeric))"
" -> Index Scan using pk_document on document ctt
(cost=0.00..8.34 rows=1 width=44)"
" Index Cond: (((ctt.acceso)::text =
(cc.acceso)::text) AND (ctt.ext_acceso = cc.ext_acceso))"

No se ven sequence scan y se nota que el gasto fuerte en join de ocurrencia
y en la busqueda por fecha. La cfg del servidor es la de defecto menos los
siguientes valores:

shared_buffers = 1GB # min 128kB
effective_cache_size = 2048MB

Es postgres 8.4. Cualquier ayuda es bienvenida de antemano.

Atte.
Leonardo Castillo L.

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message marcosrios 2013-05-03 13:55:28 Re: COPY TO a filename dinamico
Previous Message Oswaldo 2013-05-03 11:43:58 Posible Bug