Demora excesiva en Reporte de Inscripciones a Cursadas

Buenas,

La consulta que genera la operación nos está demorando casi 40 segundos para devolver 455 registros
¿Ven algo raro? ¿qué se podría hacer para mejorar la performance?

SELECT sga_ubicaciones.ubicacion AS id_ubicacion,
sga_ubicaciones.nombre AS ubicacion,
vw_actividades_plan.elemento AS id_actividad,
'(' || vw_actividades_plan.codigo || ') ' || vw_actividades_plan.nombre AS actividades,
mdp_personas.apellido || ', ' || mdp_personas.nombres as apellido_y_nombre,
mdp_tipo_documento.desc_abreviada || ' ' || mdp_personas_documentos.nro_documento as documento_principal,
mdp_personas.apellido,
mdp_personas.nombres,
mdp_personas.sexo as genero,
mdp_personas_documentos.nro_documento,
mdp_personas_documentos.tipo_documento,
mdp_personas_documentos.pais_documento,
(SELECT mdp_personas_contactos.email
FROM mdp_personas_contactos
WHERE mdp_personas_contactos.persona = mdp_personas.persona AND
mdp_personas_contactos.contacto_tipo IN ('MP','MS','MI') AND
mdp_personas_contactos.email IS NOT NULL
ORDER BY CASE mdp_personas_contactos.contacto_tipo
WHEN 'MP' THEN 1
WHEN 'MS' THEN 2
WHEN 'MI' THEN 3
ELSE 4
END
LIMIT 1) as email,
(SELECT mdp_personas_contactos.telefono_codigo_area || '|' || mdp_personas_contactos.telefono_numero
FROM mdp_personas_contactos
WHERE mdp_personas_contactos.persona = mdp_personas.persona AND
mdp_personas_contactos.contacto_tipo IN ('C','F','T','L') AND
mdp_personas_contactos.telefono_codigo_area IS NOT NULL AND
mdp_personas_contactos.telefono_numero IS NOT NULL
ORDER BY CASE mdp_personas_contactos.contacto_tipo
WHEN 'C' THEN 1
WHEN 'F' THEN 2
WHEN 'T' THEN 3
WHEN 'L' THEN 4
ELSE 5
END
LIMIT 1) as telefono,
vw_insc_cursada.inscripcion,
sga_alumnos.alumno,
sga_alumnos.legajo,
sga_alumnos.persona,
sga_alumnos.propuesta,
vw_actividades_plan.elemento,
sga_periodos.periodo,
vw_insc_cursada.plan_version,
vw_insc_cursada.comision AS id_comision,
sga_comisiones.nombre AS comision,
vw_insc_cursada.estado AS estado,
vw_insc_cursada.estado AS estado_real,
vw_insc_cursada.nro_transaccion AS nro_transaccion,
sga_turnos_cursadas.nombre AS turno,
sga_catedras.nombre AS catedra,
sga_inscripciones_estados.nombre AS estado_inscr,
to_char(vw_insc_cursada.fecha_inscripcion, 'DD/MM/YYYY HH24:MI:SS') AS fecha_inscripcion,
sga_periodos.nombre AS periodo_nombre,
sga_periodos.anio_academico,
sga_periodos.anio_academico || ' - ' || sga_periodos.nombre AS anio_periodo_nombre,
vw_actividades_plan.codigo AS cod_actividad,
vw_actividades_plan.nombre AS actividad,
sga_propuestas.nombre_abreviado AS propuesta_nombre_abreviado,
f_instancias_insc_cursada(vw_insc_cursada.inscripcion) AS instancia,
vw_insc_cursada.sq_token

FROM vw_insc_cursada
JOIN sga_comisiones ON vw_insc_cursada.comision = sga_comisiones.comision
JOIN sga_periodos_lectivos ON sga_comisiones.periodo_lectivo = sga_periodos_lectivos.periodo_lectivo
JOIN sga_periodos ON sga_periodos_lectivos.periodo = sga_periodos.periodo
JOIN vw_actividades_plan ON (vw_actividades_plan.elemento) IN
		( SELECT toba_pdtasoc_1.elemento
		 FROM vw_ug_elementos toba_pdtasoc_1
		 WHERE  ( toba_pdtasoc_1.unidad_gestion IN ('22') ) ) 
		 AND (sga_comisiones.elemento = vw_actividades_plan.elemento AND vw_insc_cursada.plan_version = vw_actividades_plan.plan_version)
JOIN sga_ubicaciones ON sga_comisiones.ubicacion = sga_ubicaciones.ubicacion
JOIN sga_alumnos ON vw_insc_cursada.alumno = sga_alumnos.alumno
JOIN mdp_personas ON sga_alumnos.persona = mdp_personas.persona
JOIN sga_propuestas ON sga_alumnos.propuesta = sga_propuestas.propuesta
JOIN sga_inscripciones_estados ON vw_insc_cursada.estado = sga_inscripciones_estados.estado
LEFT JOIN mdp_personas_documentos ON mdp_personas.documento_principal = mdp_personas_documentos.documento
LEFT JOIN mdp_tipo_documento ON mdp_personas_documentos.tipo_documento = mdp_tipo_documento.tipo_documento
LEFT JOIN sga_catedras ON sga_comisiones.catedra = sga_catedras.catedra
LEFT JOIN sga_turnos_cursadas ON sga_comisiones.turno = sga_turnos_cursadas.turno

WHERE true AND sga_periodos.anio_academico = '2022'
AND sga_periodos_lectivos.periodo_lectivo = '675'
AND sga_propuestas.propuesta = '1077'

UNION ALL
-- Rechazadas y Dadas de Baja
SELECT sga_ubicaciones.ubicacion AS id_ubicacion,
sga_ubicaciones.nombre AS ubicacion,
vw_actividades_plan.elemento AS id_actividad,
'(' || vw_actividades_plan.codigo || ') ' || vw_actividades_plan.nombre AS actividades,
mdp_personas.apellido || ', ' || mdp_personas.nombres as apellido_y_nombre,
mdp_tipo_documento.desc_abreviada || ' ' || mdp_personas_documentos.nro_documento as documento_principal,
mdp_personas.apellido,
mdp_personas.nombres,
mdp_personas.sexo as genero,
mdp_personas_documentos.nro_documento,
mdp_personas_documentos.tipo_documento,
mdp_personas_documentos.pais_documento,
(SELECT mdp_personas_contactos.email
FROM mdp_personas_contactos
WHERE mdp_personas_contactos.persona = mdp_personas.persona AND
mdp_personas_contactos.contacto_tipo IN ('MP','MS','MI') AND
mdp_personas_contactos.email IS NOT NULL
ORDER BY CASE mdp_personas_contactos.contacto_tipo
WHEN 'MP' THEN 1
WHEN 'MS' THEN 2
WHEN 'MI' THEN 3
ELSE 4
END
LIMIT 1) as email,
(SELECT mdp_personas_contactos.telefono_codigo_area || '|' || mdp_personas_contactos.telefono_numero
FROM mdp_personas_contactos
WHERE mdp_personas_contactos.persona = mdp_personas.persona AND
mdp_personas_contactos.contacto_tipo IN ('C','F','T','L') AND
mdp_personas_contactos.telefono_codigo_area IS NOT NULL AND
mdp_personas_contactos.telefono_numero IS NOT NULL
ORDER BY CASE mdp_personas_contactos.contacto_tipo
WHEN 'C' THEN 1
WHEN 'F' THEN 2
WHEN 'T' THEN 3
WHEN 'L' THEN 4
ELSE 5
END
LIMIT 1) as telefono,
vw_insc_cursada.inscripcion,
sga_alumnos.alumno,
sga_alumnos.legajo,
sga_alumnos.persona,
sga_alumnos.propuesta,
vw_actividades_plan.elemento,
sga_periodos.periodo,
vw_insc_cursada.plan_version,
vw_insc_cursada.comision AS id_comision,
sga_comisiones.nombre AS comision,
vw_insc_cursada.estado AS estado,
vw_insc_cursada.operacion AS estado_real,
vw_insc_cursada.nro_transaccion AS nro_transaccion,
sga_turnos_cursadas.nombre AS turno,
sga_catedras.nombre AS catedra,
Case vw_insc_cursada.operacion
WHEN 'B' THEN 'Baja'
WHEN 'R' THEN 'Rechazada'
END AS estado_inscr,
to_char(vw_insc_cursada.fecha_inscripcion, 'DD/MM/YYYY HH24:MI:SS') AS fecha_inscripcion,
sga_periodos.nombre AS periodo_nombre,
sga_periodos.anio_academico,
sga_periodos.anio_academico || ' - ' || sga_periodos.nombre AS anio_periodo_nombre,
vw_actividades_plan.codigo AS cod_actividad,
vw_actividades_plan.nombre AS actividad,
sga_propuestas.nombre_abreviado AS propuesta_nombre_abreviado,
f_instancias_insc_cursada_log(vw_insc_cursada.inscripcion) AS instancia,
vw_insc_cursada.sq_token

FROM vw_insc_cursada_log as vw_insc_cursada
JOIN sga_comisiones ON vw_insc_cursada.comision = sga_comisiones.comision
JOIN sga_periodos_lectivos ON sga_comisiones.periodo_lectivo = sga_periodos_lectivos.periodo_lectivo
JOIN sga_periodos ON sga_periodos_lectivos.periodo = sga_periodos.periodo
JOIN vw_actividades_plan ON (sga_comisiones.elemento = vw_actividades_plan.elemento AND vw_insc_cursada.plan_version = vw_actividades_plan.plan_version)
JOIN sga_ubicaciones ON sga_comisiones.ubicacion = sga_ubicaciones.ubicacion
JOIN sga_alumnos ON vw_insc_cursada.alumno = sga_alumnos.alumno
JOIN mdp_personas ON sga_alumnos.persona = mdp_personas.persona
JOIN sga_propuestas ON sga_alumnos.propuesta = sga_propuestas.propuesta
LEFT JOIN mdp_personas_documentos ON mdp_personas.documento_principal = mdp_personas_documentos.documento
LEFT JOIN mdp_tipo_documento ON mdp_personas_documentos.tipo_documento = mdp_tipo_documento.tipo_documento
LEFT JOIN sga_catedras ON sga_comisiones.catedra = sga_catedras.catedra
LEFT JOIN sga_turnos_cursadas ON sga_comisiones.turno = sga_turnos_cursadas.turno

WHERE true AND sga_periodos.anio_academico = '2022'
AND sga_periodos_lectivos.periodo_lectivo = '675'
AND sga_propuestas.propuesta = '1077'

ORDER BY ubicacion,
actividad,
apellido_y_nombre

Muchas gracias!

Hola Emiliano. Por favor corre la query agregando al comienzo la sentencia EXPLAIN ANALYZE. Adjunta esa salida a este foro.
Tambien proba la query pero comentando la subquery del perfil de datos:

OIN vw_actividades_plan ON
/* (vw_actividades_plan.elemento) IN
( SELECT toba_pdtasoc_1.elemento
FROM vw_ug_elementos toba_pdtasoc_1
WHERE ( toba_pdtasoc_1.unidad_gestion IN (‘22’) ) )
*/
AND (sga_comisiones.elemento = vw_actividades_plan.elemento AND vw_insc_cursada.plan_version = vw_actividades_plan.plan_version)

hola Alejandro,
Esta es la salida del analyze con el perfil de datos comentado:
(con el perfil activo la salida es distinta pero la demora es la misma)

1.	 Sort (rows=455 loops=1)	455	1
2.	 Append (rows=455 loops=1)	455	1
3.	 Nested Loop Left Join (rows=357 loops=1)	357	1
4.	 Nested Loop Left Join (rows=357 loops=1)	357	1
5.	 Nested Loop Left Join (rows=357 loops=1)	357	1
6.	 Nested Loop Left Join (rows=357 loops=1)	357	1
7.	 Nested Loop Inner Join (rows=357 loops=1)	357	1
8.	 Nested Loop Inner Join (rows=357 loops=1)	357	1
9.	 Nested Loop Inner Join (rows=357 loops=1)	357	1
10.	 Nested Loop Inner Join (rows=357 loops=1)
Join Filter: ((sga_insc_cursada.plan_version = sga_planes_versiones.plan_version) AND (sga_comisiones.elemento = sga_elementos.elemento))
357	1
11.	 Nested Loop Inner Join (rows=357 loops=1)	357	1
12.	 Hash Inner Join (rows=25839 loops=1)
Hash Cond: (sga_insc_cursada.estado = sga_inscripciones_estados.estado)
25839	1
13.	 Nested Loop Inner Join (rows=25839 loops=1)	25839	1
14.	 Nested Loop Inner Join (rows=1086 loops=1)	1086	1
15.	 Nested Loop Inner Join (rows=1 loops=1)	1	1
16.	 Index Scan using pk_sga_periodos_lectivos on sga_periodos_lectivos as sga_periodos_lectivos (rows=1 loops=1)
Index Cond: (periodo_lectivo = 675)
1	1
17.	 Index Scan using pk_sga_periodos on sga_periodos as sga_periodos (rows=1 loops=1)
Filter: (anio_academico = '2022'::numeric)
Index Cond: (periodo = sga_periodos_lectivos.periodo)
Rows Removed by Filter: 0
1	1
18.	 Index Scan using ifk_sga_comisiones_sga_periodos_lectivos on sga_comisiones as sga_comisiones (rows=1086 loops=1)
Index Cond: (periodo_lectivo = 675)
1086	1
19.	 Append (rows=24 loops=1086)	24	1086
20.	 Index Scan using ifk_sga_insc_cursada_sga_comisiones on sga_insc_cursada as sga_insc_cursada (rows=24 loops=1086)
Index Cond: (comision = sga_comisiones.comision)
24	1086
21.	 Index Scan using iu_his_insc_cursadas_comision_alumno on his_insc_cursada as his_insc_cursada (rows=0 loops=1086)
Index Cond: (comision = sga_comisiones.comision)
0	1086
22.	 Hash (rows=2 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9 kB
2	1
23.	 Seq Scan on sga_inscripciones_estados as sga_inscripciones_estados (rows=2 loops=1)	2	1
24.	 Index Scan using sga_alumnos_alumno_key on sga_alumnos as sga_alumnos (rows=0 loops=25839)
Filter: (propuesta = 1077)
Index Cond: (alumno = sga_insc_cursada.alumno)
Rows Removed by Filter: 1
0	25839
25.	 Hash Inner Join (rows=43647 loops=357)
Hash Cond: (sga_planes.propuesta = sga_propuestas_1.propuesta)
43647	357
26.	 Hash Inner Join (rows=43647 loops=357)
Hash Cond: (sga_planes_versiones.plan = sga_planes.plan)
43647	357
27.	 Hash Inner Join (rows=43647 loops=357)
Hash Cond: (sga_elementos_plan.plan_version = sga_planes_versiones.plan_version)
43647	357
28.	 Nested Loop Inner Join (rows=43647 loops=357)	43647	357
29.	 Nested Loop Inner Join (rows=6487 loops=357)	6487	357
30.	 Nested Loop Inner Join (rows=6487 loops=357)	6487	357
31.	 Index Scan using ifk_sga_g3entidades_subtipos_sga_g3entidades_tipos on sga_g3entidades_subtipos as sga_g3entidades_subtipos (rows=8 loops=357)
Index Cond: (entidad_tipo = 2)
8	357
32.	 Index Scan using ifk_sga_elementos_sga_g3entidades_subtipos on sga_elementos as sga_elementos (rows=811 loops=2856)
Index Cond: (entidad_subtipo = sga_g3entidades_subtipos.entidad_subtipo)
811	2856
33.	 Index Scan using ifk_sga_elementos_revision_sga_elementos on sga_elementos_revision as sga_elementos_revision (rows=1 loops=2315859)
Index Cond: (elemento = sga_elementos.elemento)
1	2315859
34.	 Index Scan using ifk_sga_elementos_plan_sga_elementos_revision on sga_elementos_plan as sga_elementos_plan (rows=7 loops=2315859)
Index Cond: (elemento_revision = sga_elementos_revision.elemento_revision)
7	2315859
35.	 Hash (rows=148 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 14 kB
148	1
36.	 Seq Scan on sga_planes_versiones as sga_planes_versiones (rows=148 loops=1)	148	1
37.	 Hash (rows=148 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 14 kB
148	1
38.	 Seq Scan on sga_planes as sga_planes (rows=148 loops=1)	148	1
39.	 Hash (rows=89 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 12 kB
89	1
40.	 Seq Scan on sga_propuestas as sga_propuestas_1 (rows=89 loops=1)	89	1
41.	 Index Scan using pk_sga_ubicaciones on sga_ubicaciones as sga_ubicaciones (rows=1 loops=357)
Index Cond: (ubicacion = sga_comisiones.ubicacion)
1	357
42.	 Index Scan using pk_mdp_personas on mdp_personas as mdp_personas (rows=1 loops=357)
Index Cond: (persona = sga_alumnos.persona)
1	357
43.	 Index Scan using pk_sga_propuestas on sga_propuestas as sga_propuestas (rows=1 loops=357)
Index Cond: (propuesta = 1077)
1	357
44.	 Index Scan using pk_mdp_personas_documentos on mdp_personas_documentos as mdp_personas_documentos (rows=1 loops=357)
Index Cond: (mdp_personas.documento_principal = documento)
1	357
45.	 Index Scan using pk_mdp_tipo_documento on mdp_tipo_documento as mdp_tipo_documento (rows=1 loops=357)
Index Cond: (mdp_personas_documentos.tipo_documento = tipo_documento)
1	357
46.	 Index Scan using pk_sga_catedras on sga_catedras as sga_catedras (rows=0 loops=357)
Index Cond: (sga_comisiones.catedra = catedra)
0	357
47.	 Index Scan using pk_sga_turnos_cursadas on sga_turnos_cursadas as sga_turnos_cursadas (rows=0 loops=357)
Index Cond: (sga_comisiones.turno = turno)
0	357
48.	 Limit (rows=1 loops=357)	1	357
49.	 Sort (rows=1 loops=357)	1	357
50.	 Index Scan using ifk_mdp_personas_contactos_mdp_personas on mdp_personas_contactos as mdp_personas_contactos (rows=2 loops=357)
Filter: ((email IS NOT NULL) AND ((contacto_tipo)::text = ANY ('{MP,MS,MI}'::text[])))
Index Cond: (persona = mdp_personas.persona)
Rows Removed by Filter: 3
2	357
51.	 Limit (rows=1 loops=357)	1	357
52.	 Sort (rows=1 loops=357)	1	357
53.	 Index Scan using ifk_mdp_personas_contactos_mdp_personas on mdp_personas_contactos as mdp_personas_contactos_1 (rows=2 loops=357)
Filter: ((telefono_codigo_area IS NOT NULL) AND (telefono_numero IS NOT NULL) AND ((contacto_tipo)::text = ANY ('{C,F,T,L}'::text[])))
Index Cond: (persona = mdp_personas.persona)
Rows Removed by Filter: 3
2	357
54.	 Subquery Scan (rows=98 loops=1)	98	1
55.	 Nested Loop Left Join (rows=98 loops=1)	98	1
56.	 Nested Loop Left Join (rows=98 loops=1)	98	1
57.	 Nested Loop Left Join (rows=98 loops=1)	98	1
58.	 Nested Loop Left Join (rows=98 loops=1)	98	1
59.	 Nested Loop Inner Join (rows=98 loops=1)	98	1
60.	 Nested Loop Inner Join (rows=98 loops=1)	98	1
61.	 Nested Loop Inner Join (rows=98 loops=1)	98	1
62.	 Nested Loop Inner Join (rows=3692 loops=1)	3692	1
63.	 Hash Inner Join (rows=3692 loops=1)
Hash Cond: ((sga_insc_cursada_log.plan_version = sga_planes_versiones_1.plan_version) AND (sga_comisiones_1.elemento = sga_elementos_1.elemento))
3692	1
64.	 Nested Loop Inner Join (rows=3692 loops=1)	3692	1
65.	 Nested Loop Inner Join (rows=1086 loops=1)	1086	1
66.	 Nested Loop Inner Join (rows=1 loops=1)	1	1
67.	 Index Scan using pk_sga_periodos_lectivos on sga_periodos_lectivos as sga_periodos_lectivos_1 (rows=1 loops=1)
Index Cond: (periodo_lectivo = 675)
1	1
68.	 Index Scan using pk_sga_periodos on sga_periodos as sga_periodos_1 (rows=1 loops=1)
Filter: (anio_academico = '2022'::numeric)
Index Cond: (periodo = sga_periodos_lectivos_1.periodo)
Rows Removed by Filter: 0
1	1
69.	 Index Scan using ifk_sga_comisiones_sga_periodos_lectivos on sga_comisiones as sga_comisiones_1 (rows=1086 loops=1)
Index Cond: (periodo_lectivo = 675)
1086	1
70.	 Append (rows=3 loops=1086)	3	1086
71.	 Index Scan using ifk_sga_insc_cursada_log_sga_comisiones on sga_insc_cursada_log as sga_insc_cursada_log (rows=3 loops=1086)
Index Cond: (comision = sga_comisiones_1.comision)
3	1086
72.	 Seq Scan on his_insc_cursada_log as his_insc_cursada_log (rows=0 loops=1086)
Filter: (sga_comisiones_1.comision = comision)
Rows Removed by Filter: 0
0	1086
73.	 Hash (rows=43647 loops=1)
Buckets: 65536 Batches: 1 Memory Usage: 4651 kB
43647	1
74.	 Hash Inner Join (rows=43647 loops=1)
Hash Cond: (sga_planes_1.propuesta = sga_propuestas_3.propuesta)
43647	1
75.	 Hash Inner Join (rows=43647 loops=1)
Hash Cond: (sga_planes_versiones_1.plan = sga_planes_1.plan)
43647	1
76.	 Hash Inner Join (rows=43647 loops=1)
Hash Cond: (sga_elementos_plan_1.plan_version = sga_planes_versiones_1.plan_version)
43647	1
77.	 Nested Loop Inner Join (rows=43647 loops=1)	43647	1
78.	 Nested Loop Inner Join (rows=6487 loops=1)	6487	1
79.	 Nested Loop Inner Join (rows=6487 loops=1)	6487	1
80.	 Index Scan using ifk_sga_g3entidades_subtipos_sga_g3entidades_tipos on sga_g3entidades_subtipos as sga_g3entidades_subtipos_1 (rows=8 loops=1)
Index Cond: (entidad_tipo = 2)
8	1
81.	 Index Scan using ifk_sga_elementos_sga_g3entidades_subtipos on sga_elementos as sga_elementos_1 (rows=811 loops=8)
Index Cond: (entidad_subtipo = sga_g3entidades_subtipos_1.entidad_subtipo)
811	8
82.	 Index Scan using ifk_sga_elementos_revision_sga_elementos on sga_elementos_revision as sga_elementos_revision_1 (rows=1 loops=6487)
Index Cond: (elemento = sga_elementos_1.elemento)
1	6487
83.	 Index Scan using ifk_sga_elementos_plan_sga_elementos_revision on sga_elementos_plan as sga_elementos_plan_1 (rows=7 loops=6487)
Index Cond: (elemento_revision = sga_elementos_revision_1.elemento_revision)
7	6487
84.	 Hash (rows=148 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 14 kB
148	1
85.	 Seq Scan on sga_planes_versiones as sga_planes_versiones_1 (rows=148 loops=1)	148	1
86.	 Hash (rows=148 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 14 kB
148	1
87.	 Seq Scan on sga_planes as sga_planes_1 (rows=148 loops=1)	148	1
88.	 Hash (rows=89 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 12 kB
89	1
89.	 Seq Scan on sga_propuestas as sga_propuestas_3 (rows=89 loops=1)	89	1
90.	 Index Scan using pk_sga_ubicaciones on sga_ubicaciones as sga_ubicaciones_1 (rows=1 loops=3692)
Index Cond: (ubicacion = sga_comisiones_1.ubicacion)
1	3692
91.	 Index Scan using sga_alumnos_alumno_key on sga_alumnos as sga_alumnos_1 (rows=0 loops=3692)
Filter: (propuesta = 1077)
Index Cond: (alumno = sga_insc_cursada_log.alumno)
Rows Removed by Filter: 1
0	3692
92.	 Index Scan using pk_mdp_personas on mdp_personas as mdp_personas_1 (rows=1 loops=98)
Index Cond: (persona = sga_alumnos_1.persona)
1	98
93.	 Index Scan using pk_sga_propuestas on sga_propuestas as sga_propuestas_2 (rows=1 loops=98)
Index Cond: (propuesta = 1077)
1	98
94.	 Index Scan using pk_mdp_personas_documentos on mdp_personas_documentos as mdp_personas_documentos_1 (rows=1 loops=98)
Index Cond: (mdp_personas_1.documento_principal = documento)
1	98
95.	 Index Scan using pk_mdp_tipo_documento on mdp_tipo_documento as mdp_tipo_documento_1 (rows=1 loops=98)
Index Cond: (mdp_personas_documentos_1.tipo_documento = tipo_documento)
1	98
96.	 Index Scan using pk_sga_catedras on sga_catedras as sga_catedras_1 (rows=0 loops=98)
Index Cond: (sga_comisiones_1.catedra = catedra)
0	98
97.	 Index Scan using pk_sga_turnos_cursadas on sga_turnos_cursadas as sga_turnos_cursadas_1 (rows=0 loops=98)
Index Cond: (sga_comisiones_1.turno = turno)
0	98
98.	 Limit (rows=1 loops=98)	1	98
99.	 Sort (rows=1 loops=98)	1	98
100.	 Index Scan using ifk_mdp_personas_contactos_mdp_personas on mdp_personas_contactos as mdp_personas_contactos_2 (rows=2 loops=98)
Filter: ((email IS NOT NULL) AND ((contacto_tipo)::text = ANY ('{MP,MS,MI}'::text[])))
Index Cond: (persona = mdp_personas_1.persona)
Rows Removed by Filter: 3
2	98
101.	 Limit (rows=1 loops=98)	1	98
102.	 Sort (rows=1 loops=98)	1	98
103.	 Index Scan using ifk_mdp_personas_contactos_mdp_personas on mdp_personas_contactos as mdp_personas_contactos_3 (rows=2 loops=98)
Filter: ((telefono_codigo_area IS NOT NULL) AND (telefono_numero IS NOT NULL) AND ((contacto_tipo)::text = ANY ('{C,F,T,L}'::text[])))
Index Cond: (persona = mdp_personas_1.persona)
Rows Removed by Filter: 3
2	98

El indice sga_alumnos_alumno_key lo crearon uds?
Porque al acceder a tabla alumnos, deberia acceder por el indice pk_sga_alumnos que es el indice de la PK de la tabla sga_alumnos

Corren el vacuum analyze periodicamente?

Hola Alejandro,

La verdad es que no me suena a que lo hayamos creado nosotros. De todas formas probé droppearlo y la demora es la misma.
Respecto a tu consulta sobre vacuum analizer. Sí, se hizo uno hace 2 semanas.

Emiliano, proba la siguiente query, reemplace vw_elementos_plan por las tablas que son usadas en la query:

SELECT sga_ubicaciones.ubicacion AS id_ubicacion,
sga_ubicaciones.nombre AS ubicacion,
sga_elementos.elemento AS id_actividad,
'(' || sga_elementos.codigo || ') ' || sga_elementos_plan.nombre AS actividades,
mdp_personas.apellido || ', ' || mdp_personas.nombres as apellido_y_nombre,
mdp_tipo_documento.desc_abreviada || ' ' || mdp_personas_documentos.nro_documento as documento_principal,
mdp_personas.apellido,
mdp_personas.nombres,
mdp_personas.sexo as genero,
mdp_personas_documentos.nro_documento,
mdp_personas_documentos.tipo_documento,
mdp_personas_documentos.pais_documento,
(SELECT mdp_personas_contactos.email
FROM mdp_personas_contactos
WHERE mdp_personas_contactos.persona = mdp_personas.persona AND
mdp_personas_contactos.contacto_tipo IN ('MP','MS','MI') AND
mdp_personas_contactos.email IS NOT NULL
ORDER BY CASE mdp_personas_contactos.contacto_tipo
WHEN 'MP' THEN 1
WHEN 'MS' THEN 2
WHEN 'MI' THEN 3
ELSE 4
END
LIMIT 1) as email,
(SELECT mdp_personas_contactos.telefono_codigo_area || '|' || mdp_personas_contactos.telefono_numero
FROM mdp_personas_contactos
WHERE mdp_personas_contactos.persona = mdp_personas.persona AND
mdp_personas_contactos.contacto_tipo IN ('C','F','T','L') AND
mdp_personas_contactos.telefono_codigo_area IS NOT NULL AND
mdp_personas_contactos.telefono_numero IS NOT NULL
ORDER BY CASE mdp_personas_contactos.contacto_tipo
WHEN 'C' THEN 1
WHEN 'F' THEN 2
WHEN 'T' THEN 3
WHEN 'L' THEN 4
ELSE 5
END
LIMIT 1) as telefono,
vw_insc_cursada.inscripcion,
sga_alumnos.alumno,
sga_alumnos.legajo,
sga_alumnos.persona,
sga_alumnos.propuesta,
sga_elementos.elemento,
sga_periodos.periodo,
vw_insc_cursada.plan_version,
vw_insc_cursada.comision AS id_comision,
sga_comisiones.nombre AS comision,
vw_insc_cursada.estado AS estado,
vw_insc_cursada.estado AS estado_real,
vw_insc_cursada.nro_transaccion AS nro_transaccion,
sga_turnos_cursadas.nombre AS turno,
sga_catedras.nombre AS catedra,
sga_inscripciones_estados.nombre AS estado_inscr,
to_char(vw_insc_cursada.fecha_inscripcion, 'DD/MM/YYYY HH24:MI:SS') AS fecha_inscripcion,
sga_periodos.nombre AS periodo_nombre,
sga_periodos.anio_academico,
sga_periodos.anio_academico || ' - ' || sga_periodos.nombre AS anio_periodo_nombre,
sga_elementos.codigo AS cod_actividad,
sga_elementos_plan.nombre AS actividad,
sga_propuestas.nombre_abreviado AS propuesta_nombre_abreviado,
f_instancias_insc_cursada(vw_insc_cursada.inscripcion) AS instancia,
vw_insc_cursada.sq_token

FROM vw_insc_cursada
JOIN sga_comisiones ON vw_insc_cursada.comision = sga_comisiones.comision
JOIN sga_periodos_lectivos ON sga_comisiones.periodo_lectivo = sga_periodos_lectivos.periodo_lectivo
JOIN sga_periodos ON sga_periodos_lectivos.periodo = sga_periodos.periodo
JOIN sga_elementos ON (sga_elementos.elemento) IN 
	( SELECT toba_pdtasoc_1.elemento
		 FROM vw_ug_elementos toba_pdtasoc_1
		 WHERE  ( toba_pdtasoc_1.unidad_gestion IN ('22') ) )
    AND sga_elementos.elemento = sga_comisiones.elemento
JOIN sga_elementos_revision ON sga_elEmentos_revision.elemento = sga_elementos.elemento
JOIN sga_elementos_plan ON sga_elementos_plan.elemento_revision = sga_elementos_revision.elemento_revision
     AND sga_elementos_plan.plan_version = vw_insc_cursada.plan_version
JOIN sga_ubicaciones ON sga_comisiones.ubicacion = sga_ubicaciones.ubicacion
JOIN sga_alumnos ON vw_insc_cursada.alumno = sga_alumnos.alumno
JOIN mdp_personas ON sga_alumnos.persona = mdp_personas.persona
JOIN sga_propuestas ON sga_alumnos.propuesta = sga_propuestas.propuesta
JOIN sga_inscripciones_estados ON vw_insc_cursada.estado = sga_inscripciones_estados.estado
LEFT JOIN mdp_personas_documentos ON mdp_personas.documento_principal = mdp_personas_documentos.documento
LEFT JOIN mdp_tipo_documento ON mdp_personas_documentos.tipo_documento = mdp_tipo_documento.tipo_documento
LEFT JOIN sga_catedras ON sga_comisiones.catedra = sga_catedras.catedra
LEFT JOIN sga_turnos_cursadas ON sga_comisiones.turno = sga_turnos_cursadas.turno

WHERE true AND sga_periodos.anio_academico = '2022'
AND sga_periodos_lectivos.periodo_lectivo = '675'
AND sga_propuestas.propuesta = '1077'

UNION ALL
-- Rechazadas y Dadas de Baja
SELECT sga_ubicaciones.ubicacion AS id_ubicacion,
sga_ubicaciones.nombre AS ubicacion,
sga_elementos.elemento AS id_actividad,
'(' || sga_elementos.codigo || ') ' || sga_elementos_plan.nombre AS actividades,
mdp_personas.apellido || ', ' || mdp_personas.nombres as apellido_y_nombre,
mdp_tipo_documento.desc_abreviada || ' ' || mdp_personas_documentos.nro_documento as documento_principal,
mdp_personas.apellido,
mdp_personas.nombres,
mdp_personas.sexo as genero,
mdp_personas_documentos.nro_documento,
mdp_personas_documentos.tipo_documento,
mdp_personas_documentos.pais_documento,
(SELECT mdp_personas_contactos.email
FROM mdp_personas_contactos
WHERE mdp_personas_contactos.persona = mdp_personas.persona AND
mdp_personas_contactos.contacto_tipo IN ('MP','MS','MI') AND
mdp_personas_contactos.email IS NOT NULL
ORDER BY CASE mdp_personas_contactos.contacto_tipo
WHEN 'MP' THEN 1
WHEN 'MS' THEN 2
WHEN 'MI' THEN 3
ELSE 4
END
LIMIT 1) as email,
(SELECT mdp_personas_contactos.telefono_codigo_area || '|' || mdp_personas_contactos.telefono_numero
FROM mdp_personas_contactos
WHERE mdp_personas_contactos.persona = mdp_personas.persona AND
mdp_personas_contactos.contacto_tipo IN ('C','F','T','L') AND
mdp_personas_contactos.telefono_codigo_area IS NOT NULL AND
mdp_personas_contactos.telefono_numero IS NOT NULL
ORDER BY CASE mdp_personas_contactos.contacto_tipo
WHEN 'C' THEN 1
WHEN 'F' THEN 2
WHEN 'T' THEN 3
WHEN 'L' THEN 4
ELSE 5
END
LIMIT 1) as telefono,
vw_insc_cursada.inscripcion,
sga_alumnos.alumno,
sga_alumnos.legajo,
sga_alumnos.persona,
sga_alumnos.propuesta,
sga_elementos.elemento,
sga_periodos.periodo,
vw_insc_cursada.plan_version,
vw_insc_cursada.comision AS id_comision,
sga_comisiones.nombre AS comision,
vw_insc_cursada.estado AS estado,
vw_insc_cursada.operacion AS estado_real,
vw_insc_cursada.nro_transaccion AS nro_transaccion,
sga_turnos_cursadas.nombre AS turno,
sga_catedras.nombre AS catedra,
Case vw_insc_cursada.operacion
WHEN 'B' THEN 'Baja'
WHEN 'R' THEN 'Rechazada'
END AS estado_inscr,
to_char(vw_insc_cursada.fecha_inscripcion, 'DD/MM/YYYY HH24:MI:SS') AS fecha_inscripcion,
sga_periodos.nombre AS periodo_nombre,
sga_periodos.anio_academico,
sga_periodos.anio_academico || ' - ' || sga_periodos.nombre AS anio_periodo_nombre,
sga_elementos.codigo AS cod_actividad,
sga_elementos_plan.nombre AS actividad,
sga_propuestas.nombre_abreviado AS propuesta_nombre_abreviado,
f_instancias_insc_cursada_log(vw_insc_cursada.inscripcion) AS instancia,
vw_insc_cursada.sq_token

FROM vw_insc_cursada_log as vw_insc_cursada
JOIN sga_comisiones ON vw_insc_cursada.comision = sga_comisiones.comision
JOIN sga_periodos_lectivos ON sga_comisiones.periodo_lectivo = sga_periodos_lectivos.periodo_lectivo
JOIN sga_periodos ON sga_periodos_lectivos.periodo = sga_periodos.periodo

-- JOIN vw_actividades_plan ON (sga_comisiones.elemento = vw_actividades_plan.elemento AND vw_insc_cursada.plan_version = vw_actividades_plan.plan_version)
JOIN sga_elementos ON (sga_elementos.elemento) IN 
	( SELECT toba_pdtasoc_1.elemento
		 FROM vw_ug_elementos toba_pdtasoc_1
		 WHERE  ( toba_pdtasoc_1.unidad_gestion IN ('22') ) )
    AND sga_elementos.elemento = sga_comisiones.elemento
JOIN sga_elementos_revision ON sga_elementos_revision.elemento = sga_elementos.elemento
JOIN sga_elementos_plan ON sga_elementos_plan.elemento_revision = sga_elementos_revision.elemento_revision
     AND sga_elementos_plan.plan_version = vw_insc_cursada.plan_version

JOIN sga_ubicaciones ON sga_comisiones.ubicacion = sga_ubicaciones.ubicacion
JOIN sga_alumnos ON vw_insc_cursada.alumno = sga_alumnos.alumno
JOIN mdp_personas ON sga_alumnos.persona = mdp_personas.persona
JOIN sga_propuestas ON sga_alumnos.propuesta = sga_propuestas.propuesta
LEFT JOIN mdp_personas_documentos ON mdp_personas.documento_principal = mdp_personas_documentos.documento
LEFT JOIN mdp_tipo_documento ON mdp_personas_documentos.tipo_documento = mdp_tipo_documento.tipo_documento
LEFT JOIN sga_catedras ON sga_comisiones.catedra = sga_catedras.catedra
LEFT JOIN sga_turnos_cursadas ON sga_comisiones.turno = sga_turnos_cursadas.turno

WHERE true AND sga_periodos.anio_academico = '2022'
AND sga_periodos_lectivos.periodo_lectivo = '675'
AND sga_propuestas.propuesta = '1077'

ORDER BY ubicacion,
actividad,
apellido_y_nombre

Alejandro,
Con esa modificación baja considerablemente el tiempo de ejecución. Ahora es entre 1 y 1,5 segundos
Cómo debería proceder ahora? modificando los originales?

Muchas gracias!

Hola!
Encontré este foro que plantea exactamente el mismo inconveniente que quería reportar.
Este reporte, cuando lo ejecuta un usuario con perfil de datos asociado, demora demasiado hasta que da time out la aplicación (mas de 5 minutos).
Cómo procedemos para modificar la vista que sugieren? lo modificarán para una nueva version? Nosotros estamos en la 3.20 migrando a la 3.21 en esta semana.
Saludos!

Emiliano y Maria, esto fue resuelto en version 3.21.0 (ticket #44682)
Maria, comentaste que estan migrando a versión 3.21.0. Cuando lo tengan en producción a esta version, podrás probar el reporte y nos comentas como anduvo?
Saludos!

hola Alejandro.

Como nosotros no estamos en condiciones de updatear la versión en este momento, lo que hice fue verificar que habia de nuevo en la operación y aplicarlo como parche en nuestra 3.20.1
Lo que noté es que ahora la demora de ejecución es la misma o hasta un poquito mayor. Peeero, tambien veo que en la 3.21 los cambios hechos a la consulta no fueron los que me propusiste más arriba (reemplazar la vista vw_actividades_plan por las tablas intervinientes)

Creo que la solución temporal seria dejar todo como está en nuestra 3.20.1 y reemplazar la vista por las tablas.
¿Opiniones??!

Emiliano, que metodo y archivo estas viendo?
Tal vez me confundí
Hay un cambio en el método get_listado del archivo co_inscripciones_cursadas.
Pero existe otro método el get_listado_vista que sigue consultando la vista vw_actividades_plan. ¿Es la query de este método la que estabas modificando?

Al cambiar una vista por las tablas, hay que tener en cuenta de que si es un método utilizado en un reporte, puede haber filtros que hagan referencia al a vista, en tal caso hay que cambiar el código del filtro. Por ejemplo si se busca por nombre o código de la actividad.

La query del método get_listado_alumnos_inscripciones_a_comisiones, si filtras para una comision o para un periodo lectivo, también demora? Esta query sigue utilizando la vista vw_actividades_plan.

Hola Alejandro:
Pido disculpas por la demora pero tuvimos algunos inconvenientes internos para la actualización a la 3.21.
Te comento que el reporte sigue teniendo el mismo problema. No da time out pero demora mas de 6 minutos y no llega a generar el excel.
Saludos!

Hola Maria:

  1. Cual es la version del sistema?
  2. El problema se da al recuperar los datos o una vez recuperados al generar la exportación a excel?
  3. Que filtros ingresan para recuperar las inscripciones? ¿Cuantas inscripciones estiman que son las que quieren recuperar?
  4. Realizan actualización de las estadisticas de la base de datos. Esto es correr el comando vacuum anaylze cada cierto tiempo o al menos despues de cargas masivas de datos como ser cierres de periodos lectivos, periodos de inscripción, turnos de examen…?

Hola Ale!
Te respondo:

  1. Cual es la version del sistema?
    3.21.0
  2. El problema se da al recuperar los datos o una vez recuperados al generar la exportación a excel?
    En ambos. Al recuperar los datos demora unos 6 minutos. El generar el excel no lo hace. No llega a bajarlo.
  3. Que filtros ingresan para recuperar las inscripciones? ¿Cuantas inscripciones estiman que son las que quieren recuperar?
    Filtramos por Año académico y período (obligatorios) + ubicacion, propuesta y estado de inscripcion. Con el usuario Administrador demora segundos, tanto el reporte como la bajada del excel y son 1200 registros.
  4. Realizan actualización de las estadisticas de la base de datos. Esto es correr el comando vacuum anaylze cada cierto tiempo o al menos despues de cargas masivas de datos como ser cierres de periodos lectivos, periodos de inscripción, turnos de examen…?
    Si, se realizó hace menos de 1 semana.

Gracias!

Por favor carga una solicitud. Y enviá los logs de la operación con el usuario que tarda 6 minutos la consulta.
Queremos ver la consulta que se esta realizando para analizarla y ver donde esta el problema.
Aguardamos la solicitud para seguir este tema.
Saludos.

existe un gds 65681 por este tema!

Maria, el problema planteado se resuelve por Ticket #45461 en version 3.22.0.