[Pgsql-ayuda] Aligerar consulta

Alvaro Herrera alvherre@dcc.uchile.cl
Sat, 10 Jan 2004 00:33:36 -0300


On Fri, Jan 09, 2004 at 05:56:23PM -0600, Gunnar Wolf wrote:

> Me aventé esta consultita, que sencillamente me da asco, y espero que
> alguno de ustedes me pueda sugerir cómo mejorar:
> 
> SELECT campos FROM tabla
> WHERE now()::date BETWEEN initial_date AND final_date OR
>                   (now()::date > initial_date AND final_date IS NULL) OR
>                   (initial_date IS NULL AND final_date < now()::date) OR
>                   (initial_date IS NULL AND final_date IS NULL)

Has probado usando el operador OVERLAPS?  Algo como

WHERE (now()::date, NULL) overlaps (initial_date, final_date)

Esto sabe manejar nulls (pero no el caso en que ambos extremos son
NULL -- tendrás que poner la última condición aparte)

El gran problema es que la selectividad no se puede calcular bien, y con
indices B-tree esto no anda como debiera.  Alguien mencionó en otra
lista que para esto sería mejor usar un índice rtree (o quizás un GiST
con una opclass apropiada), pensando en el tiempo como una línea y
buscar intersección de un punto (now()) con esa línea.  Yo no lo he
probado, pero posiblemente valga la pena.

Si lo haces, cuéntanos cómo te va.

Suerte,

-- 
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"Everybody understands Mickey Mouse. Few understand Hermann Hesse.
Hardly anybody understands Einstein. And nobody understands Emperor Norton."