Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to speed up Count(*) in Interbase/Firebird

Interbase is a generational database.

That's great because rollbacks are near instantaneous, but count(*) takes forever.
This is unlike e.g. MySQL where count can use an index.

I never knew why until I saw this:

Even when an index is available on the column or columns included in the COUNT, all records must be visited in order to see if they are visible under the current transaction isolation.

On wikipedia: http://en.wikipedia.org/wiki/InterBase

Any tips on how to do fast counting in Interbase/Firebird

like image 681
Johan Avatar asked Oct 12 '22 05:10

Johan


1 Answers

According to this link: http://www.firebirdfaq.org/faq5/

There is another solution. This one is by Ivan Prenosil, a long time Interbase and Firebird hacker. This solution only returns an approximate record count. As Ann W. Harrison kindly explains: Any record that has had its primary key modified will appear twice if the old version has not been garbage collected and deleted records will continue in the count until they are garbage collected.

/* 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;

This will only work on tables that have a primary key.

like image 191
Hugues Van Landeghem Avatar answered Oct 14 '22 04:10

Hugues Van Landeghem