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列的支持。TEMPORARYMEMORY就像其他任何非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表都可以增长到的值。
