From: | Alvaro Herrera <alvherre(at)surnet(dot)cl> |
---|---|
To: | "Juan P(dot) Aviles" <jputem(at)yahoo(dot)es> |
Cc: | lista postgresql <pgsql-es-ayuda(at)postgresql(dot)org> |
Subject: | Re: Otra acerca de indices |
Date: | 2005-06-30 02:13:37 |
Message-ID: | 20050630021337.GB26258@surnet.cl |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-es-ayuda |
On Thu, Jun 30, 2005 at 01:38:28AM +0200, Juan P. Aviles wrote:
> Mi pregunta tiene relacion con los indices, quisiera saber si tengo
> que generar un indice por cada posible sentencia where que tengan mis
> consultas sobre una tabla, me explico :
>
> Si tengo una tabla ' titular ' con 3 campos que consulto
> frecuentemente los cuales son tipo_tit , rut_tit , estado_tit para
> encontrar algun personaje en particular, y defino un indice con dichos
> campos, que pasa en el caso de que quiera hacer una consulta del tipo
>
> Select * from titular where tipo_tit = 2 and estado_tit = TRUE ;
Hola, en principio yo diria que eso que tienes y lo que propones es
tremendamente inefectivo.
La cualidad que buscas en un indice es que sea muy selectivo. Es decir,
si para una condicion dada un determinado indice te va a retornar la
mitad de la tabla, el indice no vale la pena.
Que quiero decir? Si tienes 4 o 5 valores para tipo_tit distintos,
en promedio (es decir con datos "de prueba" generados aleatoriamente)
cada uno de ellos abarcara el 20% o 25% de la tabla, y en casos normales
(es decir con datos de verdad) habra alguno de los valores que abarcara
una proporcion bastante mayor, y el resto un poco menos, etc. Un indice
en ese campo es muy poco selectivo por lo tanto no sirve para nada: el
costo de usar ese indice para busquedas es tan alto que mas vale hacer
un recorrido secuencial de la tabla.
Por definicion un indice en un campo booleano como estado_tit es mucho
peor. Por lo tanto los campos booleanos no sirven de nada en los
indices.
Ahora, si las consulta con estado_tit=true son muy frecuentes, y las
consultas con estado_tit=false son raras, y ademas los WHERE contienen
el tipo_tit, entonces te puede convenir un indice asi:
CREATE INDEX foo_bar on titular (tipo_tit) WHERE estado_tit = true;
esto te sirve cuando hagas estas consultas
SELECT * from titular WHERE tipo_tit=X and estado_tit=true
pero no esta
SELECT * from titular WHERE tipo_tit=X and estado_tit=false
Obviamente si haces un indice con estado_tit=true y otro con
estado_tit=false nuevamente estas perdiendo, y te conviene un solo
indice asi
CREATE INDEX foo_bar on titular (tipo_tit)
Otra cosa a tener en cuenta es que si tienes un indice
CREATE INDEX foo_bar on titular (rut_tit, tipo_tit, estado_tit)
entonces ese indice se puede usar para estas dos consultas:
SELECT * from titular WHERE rut_tit=X and tipo_tit=Y and estado_tit=Z
y
SELECT * from titular WHERE rut_tit=X and tipo_tit=Y
es decir no necesitas que en el WHERE aparezcan todas las columnas que
se mencionan en el indice.
Otra consideracion a tomar en cuenta es que cada indice agrega un costo
de procesamiento a cada INSERT, UPDATE y DELETE que es bastante grande.
No agregues indices innecesariamente porque la cosa se pone bastante
lenta.
Eso es lo que te puede aportar mi experiencia. Ojala te sirva.
--
Alvaro Herrera (<alvherre[a]surnet.cl>)
"Si un desconocido se acerca y te regala un CD de Ubuntu ...
Eso es ... Eau de Tux"
From | Date | Subject | |
---|---|---|---|
Next Message | Milton inostroza | 2005-06-30 04:17:04 | Fwd: Herramienta freeware tipo powerdesigner con soporte Postgre |
Previous Message | Ivan Figueroa | 2005-06-30 01:52:24 | Re: Otra acerca de indices |