ふと、既にメモリテーブルを実現している MySQL の 仕組みが気になったので、少し調べてみました。
ここのドキュメントを参照しました。
MEMORY ストレージエンジンはメモリ上に情報を格納するテーブルを作成します。従来、これらは HEAP テーブルと呼ばれていましたが、 現在 MEMORY テーブルへ名称変更されています。 ただし、 下位互換性があるため HEAP も引き続きサポートします。
確かに HEAP テーブルだとあんありピンと来ないです。MEMORY ストレージエンジンのいほうがいい感じです。MySQL のメモリテーブルの定義は下記の通りです。ん? USING BTREEという設定がありますね。
CREATE TABLE lookup
(id INT, INDEX USING HASH (id))
ENGINE = MEMORY;
CREATE TABLE lookup
(id INT, INDEX USING BTREE (id))
ENGINE = MEMORY;
MEMORY テーブル上に重複キーをもつハッシュインデックスがある場合(作成されるインデックスは同じ値を持つことが多い)、 キーの値に影響を与えるテーブルアップデートと、全ての消去は非常に処理が遅くなります。処理速度がどの程度落ちるかは、重複の度合いに比例します (或いは、インデックス濃度に反比例します。) 。BTREE インデックス を使用すれば、この問題は生じません。
確かに、HASH だと上記のような問題がありますね。範囲検索に使用するインデックスは HASH より BTREE を使用したほうが効率的だと思います。個人的には、CTP2 で SQL Server の メモリ最適化テーブルの生成クエリは以下のような感じになりそうな気がします。
CREATE TABLE [dbo].[FactProductInventoryInMemoryTable](
[ProductKey] [int] NOT NULL,
[DateKey] [int] NOT NULL,
[MovementDate] [date] NOT NULL,
[UnitCost] [money] NOT NULL,
[UnitsIn] [int] NOT NULL,
[UnitsOut] [int] NOT NULL,
[UnitsBalance] [int] NOT NULL,
CONSTRAINT FactProductInventoryInMemory PRIMARY KEY NONCLUSTERED HASH([ProductKey],[DateKey])
WITH (BUCKET_COUNT = 10000000),
INDEX IX1_FactProductInventoryInMemory NONCLUSTERED BTREE or RANGE ([ProductKey],[UnitCost]) WITH (BUCKET_COUNT=10000000)
) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY)
インデックスの構成とか、HASHインデックス・BTREE インデックスの特徴などを 設計する側がきちんと把握しておかないといけないですね。メモリテーブル等の機能で、DBMS は、より便利、より高速化できるようになっています。しかし、今以上に DBMS の基本をきちんと学習することも大切になってくると個人的には思っています。