MEMORY
ストレージエンジンはメモリ上に情報を格納するテーブルを作成します。従来、これらは
HEAP
テーブルと呼ばれていましたが、 現在
MEMORY
テーブルへ名称変更されています。 ただし、
下位互換性があるため HEAP
も引き続きサポートします。
各
MEMORY
テーブルは一つのディスクファイルと関連付けられています。ファイルネームはテーブルの名前で始まり、テーブル定義を格納することを示す為に拡張子 .frm
をつけます。
MEMORY
テーブル作成を明確に指示したい場合は、 ENGINE
テーブルオプションを指定します。
CREATE TABLE t (i INT) ENGINE = MEMORY;
その名前からもわかるように、MEMORY
テーブルはメモリ上に格納されます。ハッシュインデックスを使用し、処理が非常に高速で、テンポラリーテーブルを作成するのに大変便利です。ただし、サーバがクラッシュすると、この MEMORY
テーブルに格納されたすべてのデータが失われます。テーブル自体は、定義がディスク上に
.frm
ファイルで格納されているので引き続き存在しますが、サーバが再起動したときにはデータは全て失われています。
ここに例として挙げるのは、MEMORY
テーブルの作成・利用・破棄の方法です。
mysql>CREATE TABLE test ENGINE=MEMORY
->SELECT ip,SUM(downloads) AS down
->FROM log_table GROUP BY ip;
mysql>SELECT COUNT(ip),AVG(down) FROM test;
mysql>DROP TABLE test;
MEMORY
テーブルには次のような特徴があります。
MEMORY
テーブルは小さなブロックに割り当てられており、100%
動的ハッシュを使用しています。オーバーフローエリア、または追加の入力スペースは必要ありません。フリーリスト用の余分な領域も必要ありません。削除されたデータはリンクリストに保存され、テーブルに新たにデータを入力する際に再利用されます。MEMORY
テーブルでは、ハッシュテーブルでよく見られる削除+挿入の問題も起こりません。
MEMORY
テーブルは、テーブルあたり最大32インデックスまで、インデックスあたり16列、インデックスの最大幅は500バイトです。
The MEMORY
ストレージエンジンは
HASH
と BTREE
両方のインデックスを使って実行します。ここに記すように
USING
節
を追加することによりどちらのインデックスであるかを明確にすることが出来ます。
CREATE TABLE lookup (id INT, INDEX USING HASH (id)) ENGINE = MEMORY; CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY;
B-Treeインデックスとハッシュインデックスの一般的特徴は 項6.4.5. 「MySQLにおけるインデックスの使用」 に記載されています。
MEMORY
テーブルに、一意でないキーを使用出来ます
(ハッシュテーブルにはあまり見られない機能です)。
MEMORY
テーブル上に重複キーをもつハッシュインデックスがある場合(作成されるインデックスは同じ値を持つことが多い)、
キーの値に影響を与えるテーブルアップデートと、全ての消去は非常に処理が遅くなります。処理速度がどの程度落ちるかは、重複の度合いに比例します
(或いは、インデックス濃度に反比例します。)
。BTREE
インデックス
を使用すれば、この問題は生じません。
インデックスを張ったカラムが
NULL
値を含みます。
MEMORY
テーブルが固定長のレコードフォーマットを使用しています。
MEMORY
テーブルは
BLOB
や TEXT
カラムをサポートしません。
MEMORY
は AUTO_INCREMENT
カラムのサポートもしています。
INSERT DELAYED
のスレッドを
MEMORY
テーブルで使用出来ます。詳しくは項12.2.4.2. 「INSERT DELAYED
構文」を参照してください。
MEMORY
テーブルは全てのクライアント間で共有されます(他の
TEMPORARY
でないテーブルと同様)。
MEMORY
テーブルのデータはメモリ内に格納されますが、MEMORY
テーブルは、クエリ実行中サーバが作成するテンポラリーテーブルとその情報を共有します。しかしながら、MEMORY
テーブルの種類が異なる二つのテーブルは格納変換の対象となりませんが、一方テンポラリーテーブルについては:
テンポラリーテーブルのサイズが大きくなりすぎると、サーバは自動的にテーブル形式を変換してディスクに格納します。最大サイズはシステム変数
tmp_table_size
から求められます。
MEMORY
テーブルは決してディスク上のテーブルに変換されないようにします。誤った操作を行わないために、
max_heap_table_size
システム変数をセットして
MEMORY
テーブルの最大サイズを設定することが出来ます。個々のテーブルに関しては、CREATE
TABLE
ステートメントの中で
MAX_ROWS
のオプションを指定することも出来ます。
サーバには、同時に動作する全ての
MEMORY
テーブルを維持するための十分なメモリが必要です。
MEMORY
テーブルの不要になったメモリを開放するには、DELETE
または TRUNCATE
TABLE
を実行するか、DROP
TABLE
を指定してテーブルをまとめて削除します。
MySQLサーバ起動時に MEMORY
テーブルにデータを投入したい場合は、--init-file
オプションを指定します。例えば、ファイルに
INSERT INTO ... SELECT
または
LOAD DATA INFILE
iなどのステートメントを使用し、固定データソースからテーブルを取り込むことが出来ます。項4.2.2. 「コマンド オプション」、項12.2.5. 「LOAD DATA INFILE
構文」
参照。
レプリケーションを使用している場合、
シャットダウン、再起動後のマスタサーバの
MEMORY
テーブルは空になっています。ところが、スレーブはこれを認識しないため、そこにある情報は古いものとなってしまいます。マスタ起動後、マスタ上のMEMORY
テーブルを初めて使う際、DELETE
ステートメントがマスタのバイナリログに自動的に書き込まれます。このようにして、スレーブをマスタに再び一致させます。
ここで注意することは、この方法によっても、マスタ再起動からその後のテーブル使用時までのインターバル中、スレーブは依然として古いデータを保存し続けているということです。ただし、マスタ起動時
MEMORY
テーブルにデータを投入する際
--init-file
オプションを使用することにより、このインターバルタイムはゼロになります。
MEMORY
テーブル上、一行に必要なメモリは以下の表現で算出できます。
SUM_OVER_ALL_BTREE_KEYS(max_length_of_key
+ sizeof(char*) × 4) + SUM_OVER_ALL_HASH_KEYS(sizeof(char*) × 2) + ALIGN(length_of_row
+1, sizeof(char*))
ALIGN()
は行の長さを
char
ポインタサイズのちょうど倍数にするための数式です。sizeof(char*)
は32ビットマシンでは4、64ビットマシンでは8です。
追加情報
MEMORY
ストレージエンジンを専門に扱うフォーラムがあります。
http://forums.mysql.com/list.php?92.