2013-04-04 69 views
0

我有以下HSQLDB模式:爲什麼我的HSQLDB表格在磁盤上佔用太多空間?

CREATE TABLE RUNSTATS 
(
    ID  BINARY(16) NOT NULL, 
    ENTITY BLOB(128K)  NOT NULL 
    ,CHECK (PUBLIC.RUNSTATS.ID IS NOT NULL) 
    ,CHECK (PUBLIC.RUNSTATS.ENTITY IS NOT NULL) 
); 

ALTER TABLE RUNSTATS 
    ADD CONSTRAINT pk_runstats 
    PRIMARY KEY (ID); 

CREATE TABLE RUNSTATS__AVGLATENCYINDEX 
(
    ID   BINARY(16), 
    TIMESTAMP BIGINT, 
    FLOWID  VARCHAR(200), 
    AVGLATENCY DOUBLE 
); 

ALTER TABLE RUNSTATS__AVGLATENCYINDEX 
    ADD CONSTRAINT pk_runstats__avglatencyindex 
    PRIMARY KEY (ID, FLOWID); 

CREATE INDEX IDX_RUNSTATS__AVGLATENCYINDEX_FLOWID 
    ON RUNSTATS__AVGLATENCYINDEX (FLOWID ASC); 

的RUNSTATS表是x.lobs文件和RUNSTATS__AVGLATENCYINDEX - 在x.data

我插入RUNSTATS對象,其中每個在RUNSTATS表中產生1行,在RUNSTATS__AVGLATENCYINDEX中產生100行。我運行三個會話,插入100,1000和10000 RunStats對象。

另一個非常重要的細節 - 實際流ID值都正好是20個英文字符長,儘管字段爲VARCHAR(200)

請在下面找到x.data文件的磁盤使用情況彙總(含在RUNSTATS__AVGLATENCYINDEX表):

  1. 10,000行= 2.0MB
  2. 100,000行= 16MB
  3. 1,000,000行= 128MB

查閱原始計算: (整型尺寸(ID)+整型尺寸(流ID)+整型尺寸(時間戳)+整型尺寸(AVGLATENCY))= 16 + 20 + 8 + 8 = 52

所以1,000,000行應大約需要52 * 1,000,000 =〜50MB

最佳尺寸比實際少兩倍多。

這是正常的數據庫開銷嗎?我可以指示hsqldb引擎更有效地利用空間嗎?

多一點背景:

  • 實體只添加(不會被刪除)
  • 有當實體以規則的步伐,增加了一個明確的期限。例如,每10秒鐘3天。之後 - 不再添加實體。

編輯

請在這裏找到壓縮腳本文件 - https://docs.google.com/file/d/0B2pbsdBJxJI3Z2dFTndMZnBMU2c/edit?usp=sharing

回答

1

我插入1,000,000行到RUNSTATS__AVGLATENCYINDEX表和.data文件的大小爲128MB。額外的大小是由於表中的主鍵和額外索引(32字節)以及行,字符串和可空性信息的長度。 FLOWID列使用20 + 5個字節。每行總共需要32 + 12 + 4字節的額外空間,因此總數爲100字節。這被放大到32字節的倍數(FILE SCALE),導致每行128字節。

檢查您的.script文件。如果你有SET FILE SCALE 256或更高,這可能解釋額外的空間。每行的大小是此SCALE值的倍數。

使用默認的SCALE 32和給定的FLOWID大小,每行應該使用128個字節。

您還可以在數據庫中執行SHUTDOWN COMPACT,看看大小是什麼,被刪除的行已被刪除後。

您已經添加了一個鏈接到一個.script文件。 SET TABLE ...語句在大表中表示751700行。每行在磁盤上佔用128個字節。

SET FILES SCALE 32 
... 
CREATE CACHED TABLE PUBLIC.RUNSTATS(ID BINARY(16) NOT NULL PRIMARY KEY,ENTITY BLOB(128K) NOT NULL) 
CREATE CACHED TABLE PUBLIC.RUNSTATS__AVGLATENCYINDEX(ID BINARY(16),TIMESTAMP BIGINT,FLOWID VARCHAR(200),AVGLATENCY DOUBLE,PRIMARY KEY(ID,FLOWID)) 
CREATE INDEX IDX_RUNSTATS__AVGLATENCYINDEX_FLOWID ON PUBLIC.RUNSTATS__AVGLATENCYINDEX(FLOWID) 
... 
SET TABLE PUBLIC.RUNSTATS INDEX '4021 0 7517' 
SET TABLE PUBLIC.RUNSTATS__AVGLATENCYINDEX INDEX '4039 79 0 0 751700' 
+0

只有添加的行,沒有刪除。但我跑了SHUTDOWN COMPACT - 沒有任何效果,正如預期的那樣。我可以在腳本文件中看到「SET FILES SCALE 32」。 – mark 2013-04-05 01:51:49

+0

也許你有其他表格,或者表格較大。檢查.script文件以查找「SET TABLE xxx INDEX nn nn nn'語句。最後一個數字是表格的行數。 – fredt 2013-04-05 11:23:01

+0

你是對的,愚蠢的我。還有一張桌子。我將從模式中刪除它,重新運行整個測試,然後更新問題。 – mark 2013-04-05 11:48:49