查看 MonetDB 中 live/dead 个元组的数量

See number of live/dead tuples in MonetDB

我正在尝试为所有表获取一些精确的行数,因为有些表已经删除了行。我一直在使用 sys.storage.count。但这似乎也包括已删除的。

我假设使用 sys.storage 会比循环 count(*) 查询更简单、更快,尽管这两种策略在实践中可能都很好。

也许有一些统计修改的列,所以我可以减去这两个计数?

如果您只需要知道 table 中的实际行数,我建议您只使用 count(*) 查询。它非常快。即使你有 N 个 table,也很容易为每个 table.

做一个 count(*)

sys.storage 为您提供来自原始存储的信息。有了它,您可以获得漂亮的 low-level 信息,但它有一些优势。 sys.storage.count returns 存储中的计数,因此,实际上,它包括删除行,因为它们实际上并未被删除。从 2021 年 7 月版的 MonetDB 开始,删除的行会自动被新插入的行覆盖(即 auto-vacuuming)。因此,要获得实际的行数,您需要从 sys.deltas('<schema>', '<table>') 中查找 'deletes'。例如:

sql>create table tbl (id int, city string);
operation successful
sql>insert into tbl values (1, 'London'), (2, 'Paris'), (3, 'Barcelona');
3 affected rows
sql>select * from tbl;
+------+-----------+
| id   | city      |
+======+===========+
|    1 | London    |
|    2 | Paris     |
|    3 | Barcelona |
+------+-----------+
3 tuples
sql>select schema, table, column, count from sys.storage where table='tbl';
+--------+-------+--------+-------+
| schema | table | column | count |
+========+=======+========+=======+
| sys    | tbl   | city   |     3 |
| sys    | tbl   | id     |     3 |
+--------+-------+--------+-------+
2 tuples
sql>select id, deletes from sys.deltas ('sys', 'tbl');
+-------+---------+
| id    | deletes |
+=======+=========+
| 15569 |       0 |
| 15570 |       0 |
+-------+---------+
2 tuples

删除一行后,实际行数为sys.storage.count - sys.deltas ('sys', 'tbl').deletes:

sql>delete from tbl where id = 2;
1 affected row
sql>select * from tbl;
+------+-----------+
| id   | city      |
+======+===========+
|    1 | London    |
|    3 | Barcelona |
+------+-----------+
2 tuples
sql>select schema, table, column, count from sys.storage where table='tbl';
+--------+-------+--------+-------+
| schema | table | column | count |
+========+=======+========+=======+
| sys    | tbl   | city   |     3 |
| sys    | tbl   | id     |     3 |
+--------+-------+--------+-------+
2 tuples
sql>select id, deletes from sys.deltas ('sys', 'tbl');
+-------+---------+
| id    | deletes |
+=======+=========+
| 15569 |       1 |
| 15570 |       1 |
+-------+---------+
2 tuples

插入新行后,删除的行被覆盖:

sql>insert into tbl values (4, 'Praag');
1 affected row
sql>select * from tbl;
+------+-----------+
| id   | city      |
+======+===========+
|    1 | London    |
|    4 | Praag     |
|    3 | Barcelona |
+------+-----------+
3 tuples
sql>select schema, table, column, count from sys.storage where table='tbl';
+--------+-------+--------+-------+
| schema | table | column | count |
+========+=======+========+=======+
| sys    | tbl   | city   |     3 |
| sys    | tbl   | id     |     3 |
+--------+-------+--------+-------+
2 tuples
sql>select id, deletes from sys.deltas ('sys', 'tbl');
+-------+---------+
| id    | deletes |
+=======+=========+
| 15569 |       0 |
| 15570 |       0 |
+-------+---------+
2 tuples

因此,计算实际行数 (sys.storage.count - sys.deltas ('sys', 'tbl').deletes) 的公式通常适用。 sys.deltas() 保留 table 的每一列的统计信息,但是 countdeletes 是 table 宽的,所以您只需要检查一列。