optimización de consulta

From: "Marco Antonio" <marcoantoniofrias(at)gmail(dot)com>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: optimización de consulta
Date: 2007-05-30 23:55:31
Message-ID: 33e030de0705301655x5cb59dbk40f05f0d87ee7b5a@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

hola lista,

describo un poco el contexto... se ha desarrollado e implementado un
sistema educativo en java ( jdk 1.5.0), jsf (myfaces 1.1.4 y otras
librerías), hibernate (3.1.2ga) y postgresql (8.2.3 y jdbc
8.2-505.jdbc3); ahora estoy en la optimización de consultas y tengo la
siguiente situación:

la estructura:

CREATE TABLE persona (
idpersona SERIAL PRIMARY KEY,
nombres CHARACTER VARYING(100) NOT NULL,
apprimero CHARACTER VARYING(100) NOT NULL,
apsegundo CHARACTER VARYING(100) DEFAULT NULL,
ci INTEGER DEFAULT NULL,
extensionci CHARACTER VARYING(2) DEFAULT NULL,
fechanac DATE NOT NULL,
genero CHARACTER(1) NOT NULL,
paisnac CHARACTER VARYING(100) DEFAULT NULL,
ciudadnac CHARACTER VARYING(100) DEFAULT NULL,
direcciondom CHARACTER VARYING(255) DEFAULT NULL,
telefonofijo INTEGER DEFAULT NULL,
telefonomovil INTEGER DEFAULT NULL,
correoelectronico CHARACTER VARYING(255) DEFAULT NULL UNIQUE,
fecharegistro DATE NOT NULL,
UNIQUE (nombres, apprimero, apsegundo)
);

CREATE TABLE estudiante (
idpersona INTEGER NOT NULL REFERENCES persona ON DELETE CASCADE,
anoegreso INTEGER NOT NULL,
empresa CHARACTER VARYING(255) DEFAULT NULL,
cargo CHARACTER VARYING(255) DEFAULT NULL,
direccion CHARACTER VARYING(255) DEFAULT NULL,
telefonofijo INTEGER DEFAULT NULL,
certificadonac BOOLEAN NOT NULL DEFAULT FALSE,
ci BOOLEAN NOT NULL DEFAULT FALSE,
titulo BOOLEAN NOT NULL DEFAULT FALSE,
libreta BOOLEAN NOT NULL DEFAULT FALSE,
foto BOOLEAN NOT NULL DEFAULT FALSE,
PRIMARY KEY (idpersona)
);

CREATE TABLE inscrito (
idpersona INTEGER NOT NULL REFERENCES estudiante ON DELETE CASCADE,
idplanestudio INTEGER NOT NULL REFERENCES planestudio ON DELETE CASCADE,
idgestion INTEGER NOT NULL REFERENCES gestion ON DELETE CASCADE,
estado CHARACTER VARYING(50) NOT NULL,
PRIMARY KEY (idpersona, idplanestudio, idgestion)
);

las consulta:

se desea conocer todos los estudiantes inscritos en un plan de estudio
X que tengan documentacion (certificadonac, ci, titulo,libreta,foto)
faltante?... he hecho dos consultas para saber cual es la mejor (si
hay otra sugerencia... bienvenida!!!)... las "traducciones" que
hibernate hace al sql son:

consulta 1: haciendo con subconsulta...

select
distinct persona2_.idpersona as idpersona281_,
persona2_.nombres as nombres281_,
persona2_.apprimero as apprimero281_,
persona2_.apsegundo as apsegundo281_,
persona2_.ci as ci281_,
persona2_.extensionci as extensio6_281_,
persona2_.fechanac as fechanac281_,
persona2_.genero as genero281_,
persona2_.paisnac as paisnac281_,
persona2_.ciudadnac as ciudadnac281_,
persona2_.direcciondom as direcci11_281_,
persona2_.telefonofijo as telefon12_281_,
persona2_.telefonomovil as telefon13_281_,
persona2_.correoelectronico as correoe14_281_,
persona2_.fecharegistro as fechare15_281_
from
public.inscrito inscrito0_,
public.estudiante estudiante1_
inner join
public.persona persona2_
on estudiante1_.idpersona=persona2_.idpersona
where
inscrito0_.idpersona=estudiante1_.idpersona
and inscrito0_.idplanestudio=<id seleccionado por el usuario>
and (
inscrito0_.idpersona not in (
select
estudiante3_.idpersona
from
public.estudiante estudiante3_
where
estudiante3_.certificadonac=true
and estudiante3_.ci=true
and estudiante3_.titulo=true
and estudiante3_.libreta=true
and estudiante3_.foto=true
)
)
order by
persona2_.apprimero,
persona2_.apsegundo,
persona2_.nombres

su explain:

Unique (cost=281.06..299.66 rows=465 width=125)
-> Sort (cost=281.06..282.22 rows=465 width=125)
Sort Key: persona2_.apprimero, persona2_.apsegundo,
persona2_.nombres, persona2_.idpersona, persona2_.ci,
persona2_.extensionci, persona2_.fechanac, persona2_.genero,
persona2_.paisnac, persona2_.ciudadnac, persona2_.direcciondom,
persona2_.telefonofijo, persona2_.telefonomovil,
persona2_.correoelectronico, persona2_.fecharegistro
-> Hash Join (cost=183.32..260.46 rows=465 width=125)
Hash Cond: (persona2_.idpersona = inscrito0_.idpersona)
-> Seq Scan on persona persona2_ (cost=0.00..52.66
rows=2266 width=125)
-> Hash (cost=177.51..177.51 rows=465 width=8)
-> Hash Join (cost=115.75..177.51 rows=465 width=8)
Hash Cond: (estudiante1_.idpersona =
inscrito0_.idpersona)
-> Seq Scan on estudiante estudiante1_
(cost=0.00..37.46 rows=2246 width=4)
-> Hash (cost=109.93..109.93 rows=465 width=4)
-> Seq Scan on inscrito inscrito0_
(cost=37.46..109.93 rows=465 width=4)
Filter: ((idplanestudio = 4)
AND (NOT (hashed subplan)))
SubPlan
-> Seq Scan on estudiante
estudiante3_ (cost=0.00..37.46 rows=1 width=4)
Filter: (certificadonac
AND ci AND titulo AND libreta AND foto)

consulta 2: sin subconsulta...

select
distinct persona3_.idpersona as idpersona281_,
persona3_.nombres as nombres281_,
persona3_.apprimero as apprimero281_,
persona3_.apsegundo as apsegundo281_,
persona3_.ci as ci281_,
persona3_.extensionci as extensio6_281_,
persona3_.fechanac as fechanac281_,
persona3_.genero as genero281_,
persona3_.paisnac as paisnac281_,
persona3_.ciudadnac as ciudadnac281_,
persona3_.direcciondom as direcci11_281_,
persona3_.telefonofijo as telefon12_281_,
persona3_.telefonomovil as telefon13_281_,
persona3_.correoelectronico as correoe14_281_,
persona3_.fecharegistro as fechare15_281_
from
public.inscrito inscrito0_,
public.estudiante estudiante2_
inner join
public.persona persona3_ on
estudiante2_.idpersona=persona3_.idpersona,
public.estudiante estudiante1_
where
inscrito0_.idplanestudio=<id seleccionado por el usuario>
and estudiante2_.idpersona=inscrito0_.idpersona
and inscrito0_.idpersona<>estudiante1_.idpersona
and estudiante1_.certificadonac=true
and estudiante1_.ci=true
and estudiante1_.titulo=true
and estudiante1_.libreta=true
and estudiante1_.foto=true
order by
persona3_.apprimero,
persona3_.apsegundo,
persona3_.nombres

su explain:

Unique (cost=332.06..369.26 rows=930 width=125)
-> Sort (cost=332.06..334.39 rows=930 width=125)
Sort Key: persona3_.apprimero, persona3_.apsegundo,
persona3_.nombres, persona3_.idpersona, persona3_.ci,
persona3_.extensionci, persona3_.fechanac, persona3_.genero,
persona3_.paisnac, persona3_.ciudadnac, persona3_.direcciondom,
persona3_.telefonofijo, persona3_.telefonomovil,
persona3_.correoelectronico, persona3_.fecharegistro
-> Hash Join (cost=141.38..286.21 rows=930 width=125)
Hash Cond: (inscrito0_.idpersona = estudiante2_.idpersona)
-> Nested Loop (cost=75.85..206.72 rows=930 width=129)
Join Filter: (inscrito0_.idpersona <>
estudiante1_.idpersona)
-> Seq Scan on estudiante estudiante1_
(cost=0.00..37.46 rows=1 width=4)
Filter: (certificadonac AND ci AND titulo
AND libreta AND foto)
-> Hash Join (cost=75.85..157.64 rows=930 width=129)
Hash Cond: (persona3_.idpersona =
inscrito0_.idpersona)
-> Seq Scan on persona persona3_
(cost=0.00..52.66 rows=2266 width=125)
-> Hash (cost=64.22..64.22 rows=930 width=4)
-> Seq Scan on inscrito inscrito0_
(cost=0.00..64.22 rows=930 width=4)
Filter: (idplanestudio = 4)
-> Hash (cost=37.46..37.46 rows=2246 width=4)
-> Seq Scan on estudiante estudiante2_
(cost=0.00..37.46 rows=2246 width=4)

la cantidad de registros en cada la tabla inscrito -> 3298,
estudiante -> 2246, persona -> 2266... ahora estos son datos migrados
de 2 gestiones (gestion = 6meses)... de un anterior sistema y
continuan migrando hasta hacer las 10 gestiones... entonces la tabla
inscrito se incrementará considerablemente....

a mi paracer la consulta 1 (con subconsulta) es la mejor... o ud. que
sugieren???

--
Saludos...

Marco Antonio Frias Butrón
Cochabamba - Bolivia
Usuario GNU/Linux #356229 [http://counter.li.org].
Slackware 11.0

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Richard Clark 2007-05-31 00:02:12 Re: RECUPERANDO MIS BASES DE DATOS
Previous Message Gabriel Hermes Colina Zambra 2007-05-30 23:47:56 Re: Otra vez en línea postgresql.org.mx