Re: Otra acerca de indices

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"

In response to

Responses

Browse pgsql-es-ayuda by date

  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