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インデックスとハッシュインデックスの一般的特徴は How MySQL Uses Indexes に記載されています。
MEMORY テーブルに、一意でないキーを使用出来ます (ハッシュテーブルにはあまり見られない機能です)。
MEMORY テーブル上に重複キーをもつハッシュインデックスがある場合(作成されるインデックスは同じ値を持つことが多い)、 キーの値に影響を与えるテーブルアップデートと、全ての消去は非常に処理が遅くなります。処理速度がどの程度落ちるかは、重複の度合いに比例します (或いは、インデックス濃度に反比例します。) 。BTREE インデックス を使用すれば、この問題は生じません。
インデックスを張ったカラムが NULL 値を含みます。
MEMORY テーブルが固定長のレコードフォーマットを使用しています。
MEMORY テーブルは BLOB や TEXT カラムをサポートしません。
MEMORY は AUTO_INCREMENT カラムのサポートもしています。
INSERT DELAYED のスレッドを MEMORY テーブルで使用出来ます。詳細は INSERT DELAYED Syntaxをご覧ください。
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などのステートメントを使用し、固定データソースからテーブルを取り込むことが出来ます。Command Options、LOAD DATA INFILE Syntax 参照。
レプリケーションを使用している場合、 シャットダウン、再起動後のマスタサーバの 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.
