都内で働くSEの技術的なひとりごと

都内でサラリーマンやってます。マイクロソフト系(たまに、OSS系などマイクロソフト以外の技術も...)の技術的なことについて書いています。日々の仕事の中で、気になったことを技術要素関係なく気まぐれに選んでいるので記事内容は開発言語、インフラ等ばらばらです。なお、当ブログで発信、発言は私個人のものであり、所属する組織、企業、団体等とは何のかかわりもございません。ブログの内容もきちんと検証して使用してください。よろしくお願いします♪

SQL Server 2014 CTP2 で搭載されると期待される Range インデックスがどんなものか予想してみる

 ふと、既にメモリテーブルを実現している MySQL の 仕組みが気になったので、少し調べてみました。

f:id:koogucc11:20130923194238p:plain

ここのドキュメントを参照しました。

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 の基本をきちんと学習することも大切になってくると個人的には思っています。