内存表引擎
注意
在 ClickHouse Cloud 上使用 Memory 表引擎时,数据不会在所有节点之间复制(按设计)。为了保证所有查询都路由到同一个节点并且 Memory 表引擎按预期工作,您可以执行以下操作之一:
- 在同一个会话中执行所有操作
- 使用支持粘性连接的 TCP 或原生接口的客户端,例如 clickhouse-client
Memory 引擎将数据存储在 RAM 中,以未压缩的形式。数据以读取时接收的完全相同形式存储。换句话说,从该表读取是完全免费的。并发数据访问是同步的。锁很短:读写操作不会相互阻塞。不支持索引。读取是并行的。
在简单查询上可以达到最大的吞吐量(超过 10 GB/秒),因为没有从磁盘读取、解压缩或反序列化数据。(我们应该注意到,在许多情况下,MergeTree 引擎的吞吐量几乎一样高。)当重新启动服务器时,数据将从表中消失,并且表将变为空。通常,使用此表引擎是不合理的。但是,它可以用于测试,以及在相对较少行数(最多约 100,000,000 行)上需要最大速度的任务。
Memory 引擎由系统用于具有外部查询数据的临时表(请参阅“用于处理查询的外部数据”部分),以及用于实现 GLOBAL IN
(请参阅“IN 运算符”部分)。
可以指定上限和下限来限制 Memory 引擎表的大小,从而有效地使其充当循环缓冲区(请参阅 引擎参数)。
引擎参数
min_bytes_to_keep
— 内存表大小受限时要保留的最小字节数。- 默认值:
0
- 需要
max_bytes_to_keep
- 默认值:
max_bytes_to_keep
— 内存表中要保留的最大字节数,在每次插入时删除最旧的行(即循环缓冲区)。如果要删除的最旧批次的行在添加大块数据时低于min_bytes_to_keep
限制,则最大字节数可能会超过规定的限制。- 默认值:
0
- 默认值:
min_rows_to_keep
— 内存表大小受限时要保留的最小行数。- 默认值:
0
- 需要
max_rows_to_keep
- 默认值:
max_rows_to_keep
— 内存表中要保留的最大行数,在每次插入时删除最旧的行(即循环缓冲区)。如果要删除的最旧批次的行在添加大块数据时低于min_rows_to_keep
限制,则最大行数可能会超过规定的限制。- 默认值:
0
- 默认值:
用法
初始化设置
CREATE TABLE memory (i UInt32) ENGINE = Memory SETTINGS min_rows_to_keep = 100, max_rows_to_keep = 1000;
修改设置
ALTER TABLE memory MODIFY SETTING min_rows_to_keep = 100, max_rows_to_keep = 1000;
注意:可以同时设置 bytes
和 rows
限制参数,但是,将遵守 max
和 min
的下限。
示例
CREATE TABLE memory (i UInt32) ENGINE = Memory SETTINGS min_bytes_to_keep = 4096, max_bytes_to_keep = 16384;
/* 1. testing oldest block doesn't get deleted due to min-threshold - 3000 rows */
INSERT INTO memory SELECT * FROM numbers(0, 1600); -- 8'192 bytes
/* 2. adding block that doesn't get deleted */
INSERT INTO memory SELECT * FROM numbers(1000, 100); -- 1'024 bytes
/* 3. testing oldest block gets deleted - 9216 bytes - 1100 */
INSERT INTO memory SELECT * FROM numbers(9000, 1000); -- 8'192 bytes
/* 4. checking a very large block overrides all */
INSERT INTO memory SELECT * FROM numbers(9000, 10000); -- 65'536 bytes
SELECT total_bytes, total_rows FROM system.tables WHERE name = 'memory' and database = currentDatabase();
┌─total_bytes─┬─total_rows─┐
│ 65536 │ 10000 │
└─────────────┴────────────┘
同样,对于行
CREATE TABLE memory (i UInt32) ENGINE = Memory SETTINGS min_rows_to_keep = 4000, max_rows_to_keep = 10000;
/* 1. testing oldest block doesn't get deleted due to min-threshold - 3000 rows */
INSERT INTO memory SELECT * FROM numbers(0, 1600); -- 1'600 rows
/* 2. adding block that doesn't get deleted */
INSERT INTO memory SELECT * FROM numbers(1000, 100); -- 100 rows
/* 3. testing oldest block gets deleted - 9216 bytes - 1100 */
INSERT INTO memory SELECT * FROM numbers(9000, 1000); -- 1'000 rows
/* 4. checking a very large block overrides all */
INSERT INTO memory SELECT * FROM numbers(9000, 10000); -- 10'000 rows
SELECT total_bytes, total_rows FROM system.tables WHERE name = 'memory' and database = currentDatabase();
┌─total_bytes─┬─total_rows─┐
│ 65536 │ 10000 │
└─────────────┴────────────┘