En las tablas .DBF es muy rápido saber la cantidad de registros porque esa cantidad se guarda en la cabecera de cada tabla. La función RECCOUNT()  lo que hace es mostrar esa cantidad. Rapidísimo.

El Firebird a diferencia de las tablas .DBF no guarda en la Base de Datos la cantidad de filas (registros) que tienen las tablas. Por lo tanto, si se necesita conocer la cantidad total de filas lo normal es escribir un comando como el siguiente:

SELECT
   COUNT(*) AS CantidadFilas
FROM
   MiTabla

Esto funciona siempre pero …. si la tabla tiene muchas filas puede ser extremadamente lento. ¿Por qué? porque el Firebird debe recorrer la tabla secuencialmente desde la primera fila hasta la última fila e ir contándolas para poder mostrar la cantidad de ellas. Si la tabla tiene unas pocas decenas o cientos de filas no hay problema, pero si tiene millones o decenas de millones entonces ya es otro asunto.

¿Y cómo se podría acelerar?

Si necesitas utilizar frecuentemente la cantidad total de filas de una tabla y dicha tabla es muy grande, estar esperando minutos y minutos solamente para saber la cantidad total de filas puede ser impráctico e inclusive desesperante. Entonces lo que puedes hacer es lo siguiente:

  • Creas una tabla, llamada por ejemplo RECCOUNT
  • Esa tabla tendrá tres columnas:
    • REC_IDENTI. SMALLINT. Identificador (todas tus tablas deberían tener un identificador)
    • REC_NOMBRE. VARCHAR(40). Nombre de la tabla
    • REC_CANTID. INTEGER. Cantidad de registros
  • Si creas un índice según la columna REC_NOMBRE mucho mejor, será más rápido aún
  • A cada tabla de tu Base de Datos le agregas un trigger que se desencadena cuando hay un INSERT. Por ejemplo:
SELECT
   REC_CANTID
FROM
   RECCOUNT
WHERE
   REC_NOMBRE = 'ALUMNOS'
INTO
   :CantidadFilas;

CantidadFilas = iif(CantidadFilas IS NULL, 0, CantidadFilas);

UPDATE OR INSERT INTO RECCOUNT
        (REC_NOMBRE    , REC_CANTID)
 VALUES ('ALUMNOS', :CantidadFilas + 1)
MATCHING (REC_NOMBRE) ;

Entonces, cada vez que le insertes una nueva fila a la tabla ALUMNOS el contador de sus filas aumentará en 1.

Similarmente, necesitarás un trigger para disminuir la cantidad de filas cuando se borre una fila. Tendrías algo como esto:

SELECT
   REC_CANTID
FROM
   RECCOUNT
WHERE
   REC_NOMBRE = 'ALUMNOS'
INTO
   :CantidadFilas;

IF (CantidadFilas IS NOT NULL AND CantidadFilas > 0) THEN BEGIN
   UPDATE OR INSERT INTO RECCOUNT
            (REC_NOMBRE, REC_CANTID)
     VALUES ('ALUMNOS', :CantidadFilas - 1)
    MATCHING (REC_NOMBRE) ;
END

Entonces, cuando quieras saber la cantidad de filas que tiene la tabla ALUMNOS escribes:

   SELECT
      REC_CANTID
   FROM
      RECCOUNT
   WHERE
      REC_NOMBRE = 'ALUMNOS'

La diferencia en velocidad será impresionante. Ahora sí podrás utilizar en tus procesos la cantidad de filas que tiene una tabla muy grande.

About these ads