MEMORY存储引擎
MEMORY
存储引擎(以前称为HEAP
)创建具有存储在存储器中的内容的专用的表。由于数据容易受到崩溃,硬件问题或电源中断的影响,因此只能将这些表用作临时工作区或只读缓存,以存储从其他表中提取的数据。
MEMORY存储引擎功能
特征 | 支持 |
---|---|
B树索引 | 是 |
备份/时间点恢复(在服务器中而不是在存储引擎中实现。) | 是 |
集群数据库支持 | 没有 |
聚集索引 | 没有 |
压缩数据 | 没有 |
资料快取 | 不适用 |
加密数据 | 是(通过加密功能在服务器中实现。) |
外键支持 | 没有 |
全文搜索索引 | 没有 |
地理空间数据类型支持 | 没有 |
地理空间索引支持 | 没有 |
哈希索引 | 是 |
索引缓存 | 不适用 |
锁定粒度 | 表 |
MVCC | 没有 |
复制支持(在服务器中而不是在存储引擎中实现。) | 受限(请参阅本节后面的讨论。) |
储存限制 | 内存 |
T树索引 | 没有 |
交易次数 | 没有 |
更新数据字典的统计信息 | 是 |
- 何时使用MEMORY或NDB群集
- 分区
- 性能特点
- 内存表的特征
- 内存表的DDL操作
- 指标
- 用户创建的临时表
- 加载数据中
- 内存表和复制
- 管理内存使用
- 其他资源
何时使用MEMORY或NDB群集
希望部署使用MEMORY
存储引擎存储重要,高可用性或经常更新的数据的应用程序的开发人员应考虑NDB Cluster是否是更好的选择。MEMORY
引擎的典型用例涉及以下特征:
- 涉及瞬态,非关键数据的操作,例如会话管理或缓存。当MySQL服务器停止或重新启动时,
MEMORY
表中的数据将丢失。 - 内存中存储可实现快速访问和低延迟。数据量可以完全容纳在内存中,而不会导致操作系统换出虚拟内存页面。
- 只读或只读的数据访问模式(有限的更新)。
NDB Cluster提供了与MEMORY
具有更高性能级别的引擎相同的功能,并提供了以下功能不可用的其他功能MEMORY
:
- 行级锁定和多线程操作可减少客户端之间的争用。
- 即使包含写的语句混合也具有可伸缩性。
- 可选的磁盘支持操作,可确保数据持久性。
- 无共享架构和多主机操作,没有单点故障,可实现99.999%的可用性。
- 跨节点自动数据分发;应用程序开发人员无需制定自定义分片或分区解决方案。
- 不支持可变长度数据类型(包括
BLOB
和TEXT
)MEMORY
。
分区
MEMORY
表不能分区。
性能特点
MEMORY
性能受到单线程执行和处理更新时表锁开销所导致的争用的限制。当负载增加时,这会限制可伸缩性,尤其是对于包含写入的语句混合。
尽管对MEMORY
表进行内存内处理,但InnoDB
对于一般性查询或在读/写工作负载下,表不一定比繁忙服务器上的表快。特别是,执行更新所涉及的表锁定可能会减慢MEMORY
来自多个会话的表的并发使用。
根据对MEMORY
表执行的查询的类型,您可以将索引创建为默认哈希数据结构(用于基于唯一键查找单个值)或通用B树数据结构(用于所有类型的索引)。涉及相等,不相等或范围运算符(例如小于或大于)的查询。以下各节说明了创建两种索引的语法。一个常见的性能问题是在B树索引更有效的工作负载中使用默认哈希索引。
内存表的特征
该MEMORY
存储引擎不磁盘上创建任何文件。表定义存储在MySQL数据字典中。
MEMORY
表具有以下特征:
MEMORY
表的空间以小块分配。表对插入使用100%动态哈希。不需要溢出区域或额外的密钥空间。空闲列表不需要额外的空间。删除的行将放入链接列表中,并在将新数据插入表中时被重复使用。MEMORY
表也没有散列表中通常与删除和插入相关的问题。MEMORY
表使用固定长度的行存储格式。可变长度类型(例如,VARCHAR
使用固定长度存储)。MEMORY
表不能包含BLOB
或TEXT
列。MEMORY
包括对AUTO_INCREMENT
列的支持。TEMPORARY
MEMORY
就像其他任何非TEMPORARY
表一样,非表在所有客户端之间共享。
内存表的DDL操作
要创建MEMORY
表,请ENGINE=MEMORY
在CREATE TABLE
语句中指定子句。
CREATE TABLE t (i INT)ENGINE =MEMORY ;
如引擎名称所示,MEMORY
表存储在内存中。默认情况下,它们使用哈希索引,这使它们对于单值查找非常快,并且对于创建临时表非常有用。但是,当服务器关闭时,MEMORY
表中存储的所有行都会丢失。这些表本身继续存在,因为它们的定义存储在MySQL数据字典中,但是当服务器重新启动时它们为空。
本示例说明如何创建,使用和删除MEMORY
表:
mysql>CREATE TABLE testENGINE =MEMORY SELECT ip,SUM(downloads)AS downFROM log_tableGROUP BY ip; mysql>SELECT COUNT(ip),AVG(down)FROM test; mysql>DROP TABLE test;
MEMORY
表的最大大小受max_heap_table_size
系统变量的限制,系统变量的默认值为16MB。要对MEMORY
表实施不同的大小限制,请更改此变量的值。在效果的值CREATE TABLE
,或随后的ALTER TABLE
或TRUNCATE TABLE
,是用于表的寿命值。服务器重新启动还会将现有MEMORY
表的最大大小设置为全局max_heap_table_size
值。您可以按照本节后面的说明设置单个表的大小。
指标
该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树和哈希索引的一般特征,请参见“ MySQL如何使用索引”。
MEMORY
每个表最多可以有64个索引,每个索引最多16个列,最大键长为3072字节。
如果MEMORY
表哈希索引具有高度的键重复性(许多索引条目包含相同的值),则影响键值的表更新和所有删除操作的速度将显着降低。此减速的程度与重复程度成正比(或与索引基数成反比)。您可以使用BTREE
索引来避免此问题。
MEMORY
表可以具有非唯一键。(这是哈希索引实现的罕见功能。)
被索引的列可以包含NULL
值。
用户创建的临时表
MEMORY
表内容存储在内存中,这是MEMORY
表与服务器在处理查询时动态创建的内部临时表共享的属性。但是,两种类型的表的不同之处在于,这些MEMORY
表不进行存储转换,而内部临时表是:
- 如果内部临时表太大,则服务器会自动将其转换为磁盘存储,如“ MySQL中内部临时表的使用”所述。
- 用户创建的
MEMORY
表永远不会转换为磁盘表。
加载数据中
要MEMORY
在MySQL服务器启动时填充表,可以使用init_file
系统变量。例如,您可以将诸如INSERT INTO ... SELECT
或的语句LOAD DATA
放入文件中,以从持久数据源加载表,并用于init_file
命名文件。请参见“服务器系统变量”和“ LOAD DATA语句”。
内存表和复制
服务器的MEMORY
表在关闭并重新启动后将变为空。如果服务器是复制主服务器,则其从属服务器不知道这些表已为空,因此,如果从从属服务器上的表中选择数据,则会看到过期的内容。为了同步主MEMORY
表和从表,MEMORY
自启动DELETE
表以来,首次在主表上使用表时,会将一条语句写入主表的二进制日志中,以同时清空从表上的表。在主服务器重启和第一次使用该表之间的时间间隔中,从服务器仍然有过时的数据。为了避免在直接查询从站可能返回陈旧数据时出现此间隔,请使用init_file
系统变量设置为命名一个文件,该文件包含MEMORY
启动时填充主服务器上表的语句。
管理内存使用
服务器需要足够的内存来维护同时使用的所有MEMORY
表。
如果从MEMORY
表中删除单个行,则不会回收内存。仅在删除整个表时才回收内存。先前用于已删除行的内存将重新用于同一表中的新行。要MEMORY
在不再需要表的内容时释放表使用的所有内存,请执行DELETE
或TRUNCATE TABLE
删除所有行,或者完全删除表DROP TABLE
。要释放已删除的行所使用的内存,请使用ALTER TABLE ENGINE=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()
表示一个向上舍入因子,使行长成为char
指针大小的精确倍数。sizeof(char*)
在32位计算机上为4,在64位计算机上为8。
如前所述,max_heap_table_size
系统变量设置MEMORY
表的最大大小限制。要控制单个表的最大大小,请在创建每个表之前设置此变量的会话值。(max_heap_table_size
除非您打算将该值用于MEMORY
所有客户端创建的MEMORY
表,否则不要更改全局值。)以下示例创建两个表,最大大小分别为1MB和2MB:
mysql>SET max_heap_table_size = 1024*1024; Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t1 (id INT,UNIQUE (id))ENGINE =MEMORY ; Query OK, 0 rows affected (0.01 sec) mysql>SET max_heap_table_size = 1024*1024*2; Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t2 (id INT,UNIQUE (id))ENGINE =MEMORY ; Query OK, 0 rows affected (0.00 sec)
max_heap_table_size
如果服务器重新启动,则两个表都将还原为服务器的全局值。
您也可以在MAX_ROWS
表的CREATE TABLE
语句中指定表选项,MEMORY
以提示您计划存储在表中的行数。这不能使表增长到超过该max_heap_table_size
值的水平,该值仍然是最大表大小的约束。为了获得最大的灵活性,请至少将其MAX_ROWS
设置max_heap_table_size
为希望每个MEMORY
表都可以增长到的值。