Firebird dispone de un predicado llamado EXISTS() el cual nos dice si el resultado de un SELECT tiene al menos una fila.

La forma general de usarlo es la siguiente:

EXISTS (MiConsulta)

Ejemplo 1:

SELECT
   PRD_CODIGO,
   PRD_NOMBRE
FROM
   PRODUCTOS P
WHERE
   EXISTS(SELECT
             D.MOV_IDEPRD
          FROM
             MOVIMDET D
          WHERE
             D.MOV_IDEPRD = P.PRD_IDENTI AND
             D.MOV_CANTID >= 10)

Esta consulta nos mostrará todos los productos cuya cantidad vendida en una Factura sea mayor o igual que 10.

Ejemplo 2:

BEGIN

   IF (EXISTS(SELECT MiColumna FROM MiTabla WHERE MiCondición)) THEN
      -- Se cumplió la condición
   ELSE
      -- No se cumplió la condición
   END

END

 Esta construcción usaríamos dentro de un stored procedure, un trigger o un EXECUTE BLOCK.

Verificamos si se cumple la condición y luego de acuerdo al resultado realizamos una acción u otra.

Comentarios:

El predicado EXISTS() es mucho más rápido que la función agregada COUNT(*) porque EXISTS() finaliza cuando encuentra una fila que cumple la condición en cambio COUNT(*) cuenta todas las filas.

Así, si por ejemplo una tabla tiene 1.000.000 de filas, y la segunda fila cumple la condición entonces allí mismo ya finaliza EXISTS() y no recorre todas las otras filas porque no es necesario, ya sabe que la condición se cumplió. Pero COUNT(*) debe recorrer a las 1.000.000 de filas para saber cual es esa cantidad.

¿Cuándo es eficiente usar el predicado EXISTS()?

Usar EXISTS() a veces es una buena opción y a veces es una opción pésima ¿por qué? porque EXISTS() va recorriendo secuencialmente todas las filas de la tabla hasta encontrar una que cumpla la condición. Eso implica que si la tabla tiene pocas filas entonces EXISTS() finalizará rápidamente pero si la tabla tiene muchas filas entonces EXISTS() se puede demorar una eternidad si no existe lo buscado o existe pero está cerca del final.

Por lo tanto, si vas a usar el predicado EXISTS() debes preguntarte:

  • ¿Qué tan rápido es el hardware?
  • ¿Cuántas filas tiene la tabla AHORA?
  • ¿Cuántas filas tendrá la tabla dentro de un año, dos años, tres años, …, ocho años?
  • ¿Cuánto tiempo puede demorar la consulta sin que el usuario quiera romper una silla de la bronca?

En general, y al momento de escribir este artículo, si una tabla tiene 100.000 filas o menos entonces se puede usar EXISTS() sin mayor problema. Desde luego que a medida que vaya pasando el tiempo esa cantidad de filas se incrementará porque el hardware será cada vez más y más rápido.

Si sabes que tu tabla tiene o tendrá o puede llegar a tener varios millones de filas, entonces no uses el predicado EXISTS() porque la consulta será extremadamente lenta.

Así que, hoy por hoy, si estás 100% seguro de que la tabla nunca alcanzará a las 100.000 filas, puedes usar EXISTS() sin problema. Pero si la tabla tiene, tendrá, o puede llegar a tener más de 100.000 filas entonces verifica la velocidad con la computadora más lenta que tienes disponible y si obtienes un tiempo de respuesta aceptable.

Artículos relacionados:

Los predicados existenciales

El índice del blog Firebird21