PDA

Ver la Versión Completa : Coalesce en índice de firebird


mightydragonlor
26-06-2012, 02:41:18
Hola a todos, hace un tiempo leí en un hilo de este mismo foro, la forma de crear un índice con Coalesce para mejorar el desempeño de las consultas, pero desafortunadamente no lo encuentro, basicamente lo que necesito es que al hacer una consulta del tipo:


Select
T.A,T.B,T.C FROM TABLA T
WHERE
A = COALESCE(:A, T.A)
AND B = COALESCE(:B, T.B)
AND C = COALESCE(:C, T.C)


Muchas gracias de antemano.

Chris
26-06-2012, 03:51:31
COALENCE no es para mejorar el desempeño de la consulta. COALENCE es un operador seguro para evaluar Nulos. Lee: http://www.firebirdsql.org/refdocs/langrefupd15-coalesce.html

Entonces, COALENCE podría decirse que funciona así:
COALANCE(Value, Value2, Value3) equivaldrá a:

IF (Value is not NULL) then result := Value
elseif (Value2 is not NULL) then result := Value2
elseif (Value3 is not NULL) then result := value3
...


COALENCE devolverá el primer parámetro que no sea NULL. Recuerda que, a excepción de "IS", no puedes utilizar los operadores para hacer comparaciones con NULL. Ya que el valor de NULL no está definido según el estándar SQL.

Saludos.

Casimiro Notevi
26-06-2012, 09:12:49
Sólo recordar que es 'coalesce', no coalence.

mightydragonlor
26-06-2012, 15:10:28
COALENCE no es para mejorar el desempeño de la consulta. COALENCE es un operador seguro para evaluar Nulos. Lee: http://www.firebirdsql.org/refdocs/langrefupd15-coalesce.html

Entonces, COALENCE podría decirse que funciona así:
COALANCE(Value, Value2, Value3) equivaldrá a:

IF (Value is not NULL) then result := Value
elseif (Value2 is not NULL) then result := Value2
elseif (Value3 is not NULL) then result := value3
...


COALENCE devolverá el primer parámetro que no sea NULL. Recuerda que, a excepción de "IS", no puedes utilizar los operadores para hacer comparaciones con NULL. Ya que el valor de NULL no está definido según el estándar SQL.

Saludos.

Gracias por tu comentario Chris, conozco perfectamente como funciona Coalesce, pero hay un problema, en consultas con muchos parámetros, las cuales deben hacerse en tablas con una gran cantidad de datos empieza a generar Tables Scan, hace algún tiempo leí que puedes crear un índice a una tabla que puede hacer que cuando uses el Coalesce no haga el Table Scan y use ese índice optimizado para el Coalesce.
Muchas gracias, Saludos.

Chris
26-06-2012, 16:26:15
Sinceramente nunca había escuchado sobre este asunto. Es interesante todo esto que estás diciendo.

guillotmarc
26-06-2012, 17:59:09
Hola.

Puedes utilizar un Expression Index (Índice sobre expresión). Mira la documentación sobre CREATE INDEX.

http://www.firebirdsql.org/refdocs/langrefupd20-create-index.html

Aunque no va a funcionar para el ejemplo concreto que has dado, puesto que tu expresión tiene parámetros, y por tanto no es posible evaluarla en el momento de insertar un registro (cuando se crea una entrada en el índice). Solo se puede evaluar en el momento de lanzar la consulta con unos parámetros concretos.

Es decir :

Esta expresión se puede optimizar mediante un índice.

create index ix_T on T computed by (coalesce(A, ''));

Pero esta expresión no se puede optimizar (no puedes indicar parámetros que solo existen en tiempo de lanzar la consulta).

create index ix_T on T computed by (coalesce(:A, A));

Saludos.

Chris
26-06-2012, 18:07:17
Yo creo que talvez a lo que te refieres es a esto:
http://weblogs.sqlteam.com/jeffs/archive/2007/09/18/sql-conditional-where-clauses.aspx

mightydragonlor
26-06-2012, 21:29:31
Gracias guillotmarc y Chris por sus respuestas, la verdad es que ambas me han servido mucho, muchísimas gracias =)