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.