5

Interbase は世代別データベースです。

count(*)ロールバックはほぼ瞬時に行われますが、永遠にかかるため、これは素晴らしいことです。
これは、count がインデックスを使用できる MySQL など とは異なります。

これを見るまで理由がわかりませんでした:

COUNT に含まれる 1 つまたは複数の列でインデックスを使用できる場合でも、現在のトランザクション分離でそれらが表示されるかどうかを確認するには、すべてのレコードにアクセスする必要があります。

ウィキペディア: http://en.wikipedia.org/wiki/InterBase

Interbase/Firebird で高速カウントを行う方法に関するヒント

4

2 に答える 2

4

このリンクによると:http ://www.firebirdfaq.org/faq5/

別の解決策があります。これは、長年のInterbaseおよびFirebirdハッカーであるIvanPrenosilによるものです。このソリューションは、おおよそのレコード数のみを返します。Ann W. Harrisonが親切に説明しているように、古いバージョンがガベージコレクションされていない場合、主キーが変更されたレコードは2回表示され、削除されたレコードはガベージコレクションされるまでカウントされ続けます。

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

これは、主キーを持つテーブルでのみ機能します。

于 2011-04-28T11:44:26.657 に答える
0

カウントするテーブルに対して2つのトリガーを作成することもできます。このソリューションは、多くの「アクション」がある特別なテーブルを対象としています。

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

その後、その特別なテーブルの数を知る必要がある場合は、COUNTING_TABLEから選択するだけです。

SELECT LINES FROM COUNTING_TABLE
WHERE TABLE='TABLE_NAME' /* Table name here*/
于 2011-06-08T18:32:19.660 に答える