0

我有以下 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 对象。

另一个非常重要的细节 - 实际的 FLOWID 值都是 20 个英文字符长,尽管字段是 VARCHAR(200)

请在下面找到x.data文件的磁盘使用摘要(包含 RUNSTATS__AVGLATENCYINDEX 表):

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

现在原始计算: (sizeOf(ID) + sizeOf(FLOWID) + sizeOf(TIMESTAMP) + sizeOf(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

4

1 回答 1

1

我在 RUNSTATS__AVGLATENCYINDEX 表中插入了 1,000,000 行,.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'
于 2013-04-04T20:38:41.320 回答