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— メモリテーブル内で保持する最大バイト数。各 insert 時に最も古い行が削除されます (つまり循環バッファ) 。大きな ブロック を追加する際、削除対象となる最も古い行のまとまりを削除するとmin_bytes_to_keepの制限を下回る場合、最大バイト数は指定した上限を超えることがあります。- デフォルト値:
0
- デフォルト値:
min_rows_to_keep— メモリテーブルにサイズ上限が設定されている場合に保持する最小行数。- デフォルト値:
0 max_rows_to_keepが必要
- デフォルト値:
max_rows_to_keep— メモリテーブル内で保持する最大行数。各 insert 時に最も古い行が削除されます (つまり循環バッファ) 。大きな ブロック を追加する際、削除対象となる最も古い行のまとまりを削除すると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 と 行 の上限指定パラメータは同時に設定できますが、実際に適用されるのは 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 │
└─────────────┴────────────┘