Re: [Pgsql-ayuda] Tiempo de respuesta

From: Alberto Caso <alberto(dot)caso(at)adaptia(dot)net>
To: Patricio Muñoz <pmunoz(at)cmet(dot)net>
Cc: Pgsql-ayuda(at)tlali(dot)iztacala(dot)unam(dot)mx
Subject: Re: [Pgsql-ayuda] Tiempo de respuesta
Date: 2003-09-26 03:12:33
Message-ID: 1064545949.25714.37.camel@localhost
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

El jue, 25-09-2003 a las 23:13, Patricio Muñoz escribió:
> > Hola:
> >
> > El jue, 25-09-2003 a las 21:26, Patricio Muñoz escribió:
> > > Tengo una tabla con 2.063.478 de registros. Al ejecutar la consulta por
> ej.
> > > SELECT * FROM particular WHERE telefono LIKE '00%960766' AND
> region='05';
[...]
> >¿Los teléfonos empiezan por números muy diferentes o todos comienzan por
> '00'?
> Todos comienzan por '00'
>

¿Tus consultas siempre serán con el '%' en la tercera posición o
tendrás unas veces '00%960766' y otras '00696%766", etc?

Si siempre vas a tener el % en el mismo sitio, puedes crear un índice
usando los caracteres que están a partir de la posición siguiente.

Para ello te debes crear una función que devuelva la subcadena formada
por dichos caracteres, por ejemplo:

create function substr4_7(text) returns text immutable as '
begin
return substr($1,4,7);
end;
' language 'plpgsql';

(Aquí estoy suponiendo que el primer caracter que viene después del % es
el que ocupa la posición 4ª del número de teléfono y que dicho número es
de 10 caracteres).

Después te creas un índice funcional usando esa nueva función:

create index particular_substr4_7_telefono_idx on particular
(substr4_7(telefono));

Y cambias tu consulta para que use substr4_7 en lugar de LIKE:

select * from particular where substr3_10(telefono)= '76589786' and
region=8;

Para probar, he creado una tabla con 2.100.000 registros y los
resultados en mi equipo son:

explain analyze select * from particular where telefono like
'00%6589786' and region=8;
QUERY PLAN
----------------------------------------------------------------------
Seq Scan on particular (cost=0.00..46021.42 rows=2 width=22) (actual
time=14705.76..16577.43 rows=1 loops=1)
Filter: ((telefono ~~ '00%6589786'::text) AND (region = 8))
Total runtime: 16577.67 msec

explain analyze select * from particular where substr4_7(telefono)=
'6589786' and region=8;
QUERY PLAN
----------------------------------------------------------------------
(cost=0.00..39508.56 rows=751 width=22) (actual time=0.23..0.24 rows=1
loops=1)
Index Cond: (substr4_7((telefono)::text) = '6589786'::text)
Filter: (region = 8)
Total runtime: 0.45 msec

En tu caso puede variar dependiendo de la dispersión de los números de
teléfono (en mi caso eran números aleatorios y, por tanto, muy
dispersos).

Una mejor solución (sobre todo si no siempre tienes el % en la misma
posición) puede ser la que apunta Álvaro de crear un índice con el
número invertido, aunque no sé muy bien cómo interactuará con el LIKE,
por lo que otra opción es guardar el número ya invertido en la tabla
(pero eso tendrá el incordio de tener que cambiar muchas cosas en tu
aplicación).

Saludos.

--
Alberto Caso Palomino
Adaptia Soluciones Integrales
http://www.adaptia.net
alberto(dot)caso(at)adaptia(dot)net

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Pablo 2003-09-26 12:12:25 [Pgsql-ayuda] Funcion para encriptar
Previous Message Alvaro Herrera 2003-09-25 22:38:02 Re: [Pgsql-ayuda] Tiempo de respuesta