Pregunta

Interbase es una base de datos generacional.

Eso es genial porque las reversiones son casi instantáneas, pero count(*) Toma una eternidad.
Esto es diferente a por ejemplo, MySQL donde el recuento puede usar un índice.

Nunca supe por qué hasta que vi esto:

Incluso cuando hay un índice disponible en la columna o columnas incluidas en el recuento, todos los registros deben visitarse para ver si son visibles bajo el aislamiento de la transacción actual.

En Wikipedia: http://en.wikipedia.org/wiki/interbase

Cualquier consejo sobre cómo hacer un recuento rápido en Interbase/Firebird

¿Fue útil?

Solución

Según este enlace: http://www.firebirdfaq.org/faq5/

Hay otra solución. Este es de Ivan Prenosil, una base de tiempo y hacker de Firebird desde hace mucho tiempo. Esta solución solo devuelve un recuento de registros aproximado. Como Ann W. Harrison explica amablemente: cualquier registro que haya tenido su clave principal modificada aparecerá dos veces si la versión anterior no ha sido recolectada de basura y los registros eliminados continuarán en el recuento hasta que se recolecten basura.

/* first update the statistics */
UPDATE RDB$INDICES SET RDB$STATISTICS = -1;
COMMIT;

/* Display table names and record counts */
SELECT RDB$RELATIONS.RDB$RELATION_NAME,
CASE 
WHEN RDB$INDICES.RDB$STATISTICS = 0 THEN 0 
ELSE CAST(1 / RDB$INDICES.RDB$STATISTICS AS INTEGER) 
END 
FROM RDB$RELATIONS 
LEFT JOIN RDB$RELATION_CONSTRAINTS 
 ON RDB$RELATIONS.RDB$RELATION_NAME = RDB$RELATION_CONSTRAINTS.RDB$RELATION_NAME 
 AND RDB$CONSTRAINT_TYPE = 'PRIMARY KEY'
LEFT JOIN RDB$INDICES 
  ON RDB$RELATION_CONSTRAINTS.RDB$INDEX_NAME = RDB$INDICES.RDB$INDEX_NAME 
WHERE RDB$VIEW_BLR IS NULL AND RDB$RELATION_ID >= 128 
ORDER BY 1;

Esto solo funcionará en tablas que tienen una clave principal.

Otros consejos

También puede hacer 2 desencadenantes para la mesa que desea contar. Esta solución está destinada a algunas tablas especiales donde tienes mucha "acción".

CREATE TRIGGER TABLE_BI0 ACTIVE BEFORE INSERT
BEGIN
   UPDATE COUNTING_TABLE
   SET LINES=LINES + 1
   WHERE TABLE='TABLE_NAME'; /* Table name here*/
END


CREATE TRIGGER TABLE_BD0 ACTIVE BEFORE DELETE
BEGIN
   UPDATE COUNTING_TABLE
   SET LINES=LINES - 1
   WHERE TABLE='TABLE_NAME'; /* Table name here*/
END

Después de eso, cuando necesite conocer el recuento de esa tabla especial, simplemente lo seleccione de Counting_Table

SELECT LINES FROM COUNTING_TABLE
WHERE TABLE='TABLE_NAME' /* Table name here*/
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top