Interbase是一個世代數據庫。如何加快Interbase/Firebird中的計數(*)
這很棒,因爲回滾幾乎是瞬間的,但count(*)
需要永遠。
這是不像例如,其中count可以使用索引的MySQL。
我從來不知道爲什麼,直到我看到了這一點:
即使索引可對列或包含在計數列,所有的記錄都必須爲了參觀,看看他們是下可見當前事務隔離。
維基百科:http://en.wikipedia.org/wiki/InterBase
如何做到快速計數的InterBase /火鳥
Interbase是一個世代數據庫。如何加快Interbase/Firebird中的計數(*)
這很棒,因爲回滾幾乎是瞬間的,但count(*)
需要永遠。
這是不像例如,其中count可以使用索引的MySQL。
我從來不知道爲什麼,直到我看到了這一點:
即使索引可對列或包含在計數列,所有的記錄都必須爲了參觀,看看他們是下可見當前事務隔離。
維基百科:http://en.wikipedia.org/wiki/InterBase
如何做到快速計數的InterBase /火鳥
根據此鏈接的任何提示:http://www.firebirdfaq.org/faq5/
還有另一種解決方案。這是Ivan Prenosil,很久以前的Interbase和Firebird黑客。該解決方案僅返回近似記錄數。正如Ann W.Harrison善意地解釋的那樣:如果舊版本沒有被垃圾收集,並且刪除的記錄將繼續計數直到它們被垃圾收集,那麼任何修改了主鍵的記錄都會出現兩次。
/* 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;
這隻適用於具有主鍵的表格。
您還可以爲要計數的表製作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*/
海事組織是一個糟糕的主意,特別是有很多「行動」的表格。對獨立的表進行併發操作時,都會嘗試在COUNTING_TABLE中寫入相同的記錄,這可能會導致鎖衝突。 – mghie 2011-06-08 20:45:14
你說得對@mghie,但是如果它有很多動作,肯定會發生在非常短的交易中,從而最大限度地減少鎖定時間/衝突。在應用此工作周之前,您應該非常重視您的考慮因素。 – 2011-06-13 22:12:16
@Hughes,感謝您的鏈接選擇它。 – Johan 2011-04-28 12:33:34