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
- 默认值:
compress- 是否压缩内存中的数据。- 默认值:
false
- 默认值:
用法
初始化设置
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 │
└─────────────┴────────────┘