MySQL Memory 存储引擎浅析 (二)

2014-11-24 10:40:22 · 作者: · 浏览: 1
制将使用max_heap_table_size 的值重置。)

服务器需要足够内存来维持所有在同一时间使用的MEMORY表。

如果删除行,内存表不会回收内存,只有整张表全部删除的时候,才进行内存回收。同时只有在同一张表中插入新行时才会使用之前删除行的内存空间。 要释放已删除行所占用的内存空间,可以使用ALTER TABLE ENGINE=MEMORY对表进行强制重建。当内容过期要释放整张内存表,可以执行DELETE 或TRUNCATE TABLE清除所有行,或者使用DROP TABLE删除表。

当MySQL服务器启动时,如果你想填充MEMORY表,你可以使用--init-file选项。例如,你可以把INSERT INTO ... SELECT 或LOAD DATA INFILE这样的语句放入这个文件中以便从持久稳固的的数据源装载表。

如果你正使用复制,当主服务器被关闭且重启动之时,主服务器的MEMORY表变空。可是从服务器意识不到这些表已经变空,所以如果你从它们选择数据,它就返回过时的内容。自从服务器启动后,当一个MEMORY表在主服务器上第一次被使用之时,一个DELETE FROM语句被自动写进主服务器的二进制日志,因此再次让从服务器与主服务器同步。注意,即使使用这个策略,在主服务器的重启和它第一次使用该表之间的间隔中,从服务器仍旧在表中有过时数据。可是,如果你使用--init-file选项于主服务器启动之时在其上推行MEMORY表。它确保这个时间间隔为零。

在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()代表round-up因子,它使得行的长度为char指针大小的确切倍数。sizeof(char*)在32位机器上是4,在64位机器上是8。

如前所述,系统变量max_heap_table_size 用于设置内存表的大小上限。要控制单个表的最大值,需要在创建表之前设置会话变量。(不要设置全局max_heap_table_size 的值,除非你打算所有客户端创建的内存表都使用这个值)

下面的例子创建了两张内存表,它们的大小限制分别为1MB 和2MB:

SET max_heap_table_size = 1024*1024;

/* Query OK, 0 rows affected (0.00 sec) */

CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;

/* Query OK, 0 rows affected (0.01 sec) */

SET max_heap_table_size = 1024*1024*2;

/* Query OK, 0 rows affected (0.00 sec) */

CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;

/* Query OK, 0 rows affected (0.00 sec) */

如果服务重启,两张表的大小限制会使用全局的max_heap_table_size值复原。

你也可以通过CREATE TABLE 的MAX_ROWS选项设置表的最大行数,但max_heap_table_size的优先级高于MAX_ROWS,当两者同时存在时为了最大兼容,你需要将max_heap_table_size设置一个合理值。

Memory存储引擎官方论坛:http://forums.mysql.com/list.php 92

性能测试

分别测试比较了MySQL的InnoDB、MyIsam、Memory三种引擎与.Net DataTable的Insert以及Select性能(柱状图体现了其消耗时间,单位百纳秒,innodb_flush_log_at_trx_commit参数配置为1,每次测试重启了MySQL以避免Query Cache),大至结果如下:

\

写入10000条记录比较。

\

读取1000条记录比较。

测试脚本:

/******************************************************

MYSQL STORAGE ENGINE TEST

http://wu-jian.cnblogs.com/

2011-11-29

******************************************************/

CREATE DATABASE IF NOT EXISTS test

CHARACTER SET 'utf8'

COLLATE 'utf8_general_ci';

USE test;

/******************************************************

1.INNODB

******************************************************/

DROP TABLE IF EXISTS test_innodb;

CREATE TABLE IF NOT EXISTS test_innodb (

id INT UNSIGNED AUTO_INCREMENT COMMENT 'PK',

obj CHAR(255) NOT NULL DEFAULT '' COMMENT 'OBJECT',

PRIMARY KEY (id)

) ENGINE=INNODB;

/******************************************************

2.MYISAM

******************************************************/

DROP TABLE IF EXISTS test_myisam;

CREATE TABLE IF NOT EXISTS test_myisam (

id INT UNSIGNED AUTO_INCREMENT COMMENT 'PK',

obj CHAR(255) NOT NULL DEFAULT '' COMMENT 'OBJECT',

PRIMARY KEY (id)

) ENGINE=MYISAM;

/******************************************************

1.MEMORY

******************************************************/

DROP TABLE IF