[Pgsql-ayuda] Tiempo de respuesta

Alberto Caso alberto.caso@adaptia.net
Fri, 26 Sep 2003 05:12:33 +0200


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.caso@adaptia.net