Firebird: Row Counter
1. Einleitung
- Auf firebirdsql.org, im Generator Guide
- In The Firebird FAQ werden unter Select count(*) is slow zwei Möglichkeiten beschrieben:
- Eine Zähltabelle, in der bei jeder Einfüge- und Löschoperation ein Datensatz mit +1 bzw. -1 und der Tabellenname eingetragen wird. Mittels der Aggregatfunktion SUM() wird dann die Anzahl der Datensätze, gruppiert nach Tabellennamen, ermittelt. Um die Tabelle klein zu halten, müssen regelmäßig die einzelnen Datensätze pro Tabellennamen aufsummiert und als einziger Datensatz abgelegt werden.
- Die Ermittlung der Datensatzanzahl über die Statistik des Primäschlüssels oder eines anderen eindeutigen Index. Da die Statistik eines Index der reziproke Wert der Datensatzanzhl ist, kann die Datensatzanzahl mi 1/Statistikwert berechnet werden. Hierbei kann es allerdings zu Rundungsbroblemen kommen, weil das Feld RDB$STATISTICS in RDB$INDICES einen DOUBLE PRECISION Wert enthält.
Hier wird eine Variante aus Trigger und Zähltabelle beschrieben, die Transaktionssicher ist und sich auch für Zählungen anderer Datensatzeigenschaften, z.B. eines Aktiv-Flags, eignet.
Zählung
Die einzelnen Zähldatensätze werden innerhalb einer Transaktion in der globalen temporären Tabelle "_TABLE_ROW_COUNT" gespeichert. Der Typ dieser Tabelle ist ON COMMIT DELETE ROWS, damit die aktuelle Zählung nur innerhalb dieser Transaktion gültig ist. In jedem Datensatz wird der Generator vermerkt, auf den die bei einem COMMIT auszuführende Auswertung wirksam wird.
CREATE GLOBAL TEMPORARY TABLE "_TABLE_ROW_COUNT" (
"rcn_generator" "dom_SYS$NAME" NOT NULL,
"rcn_count" "dom_INT16" NOT NULL
) ON COMMIT DELETE ROWS;
Auswertung
Die Auswertung erfolgt in einem Datenbank-Trigger, der bei einem COMMIT gefeuert wird. Innerhalb dieses Triggers werden alle Datensätze, gruppiert nach Zielgenerator, aufsummiert und daraus eine EXECUTE BLOCK Statement gebaut. Dieses Statement in einem VARCHAR wird dann mittels EXECUTE STATEMENT ausgeführt, um den zugehörigen Generator zu aktualisieren.