原标题:MySQL MEMORY 引擎及性能比对

同事咨询MySQL MEMORY引擎的细节,能否满足需求。没有太多了解,这里做个系统总结。

MEMORY存储引擎创建的表数据只能保存在内存。

MySQL宕机、硬件故障或者意外掉电,都会造成MEMORY引擎表丢失数据。所以,MEMORY表中的数据来源于其他表(可落盘永久保存)用于只读适用,或者用于临时工作起到数据周转。

MEMORY 存储引擎特性

[a] Implemented in the server (via encryption functions). Data-at-rest tablespace encryption is available in MySQL 5.7 and later.

[b] Implemented in the server, rather than in the storage engine.

[c] Implemented in the server, rather than in the storage engine.

来源: https://dev.mysql.com/doc/refman/5.6/en/memory-storage-engine.html

何时使用MEMORY

临时使用、不重要的数据,例如网站的会话管理和缓存。可接受数据丢失。

发挥其访问快、低延迟特性

只读或者大部分是读操作,不适合大量写操作。

性能特性

内存表受限于单线程执行和表级锁引起的争用。在负载增加时限制了可扩展性,特别是写操作。

尽管内存表在内存中处理,在繁忙的服务网上,并不一定比InnoDB表更快,如一般查询或者读写场景。特别是,多个会话执行update操作会造成性能低下。

根据不同的SQL查询,需要创建内存表的默认hash索引(基于键的单个值查询),或者B-tree索引(等值查询、不等值查询或者范围查询)。

内存表的物理特性

每张内存表会在硬盘上创建一个文件,用于保存表结构(没有数据)。文件名为以内存表名开始,.frm结尾。

特性

内存表的空间使用小块(small block)。表使用100%动态hash插入。已删除的行放到空闲列表中,下次插入新数据会被使用。

使用定长的行存储格式。变长类型存入内存表需转换为定长。

不支持BLOB、TEXT类型的列。

内存表支持自增列(AUTO_INCREMENT)

不能在多个会话上共享临时表。

内存表的DDL操作

创建临时表

CREATE TABLE t (i INT) ENGINE = 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;

内存表的较大受限于 max_heap_table_size 参数,默认为16MB。根据场景需自己调整该参数。

索引

MEMORY存储引擎支持HASH和BTREE索引。

CREATE TABLE lookup

(id INT, INDEX USING HASH (id))

ENGINE = MEMORY;

CREATE TABLE lookup

(id INT, INDEX USING BTREE (id))

ENGINE = MEMORY;

每张内存表可创建64个索引,每个索引较大支持16个列,一个key的长度较大值为3072bytes。

如果一个内存表hash索引的键值有很高的重复度,更新键值、删除操作速度都会显著降低。这种速度下降的程度与键值重复度成正比。您可以使用BTREE索引来规避这个问题。

内存表可以有非键(这是hash索引不常用的功能)。

索引列中可包含NULL值。

加载数据

MySQL启动时,加入--init-file选项,将下列命令加入到这个文件中,保证启动后内存表中有数据。

INSERT INTO ... SELECT

LOAD DATA INFILE

内存表和复制(Replication)

服务器重启会导致内存表数据丢失。如果是主库,从库没有意识到主库表中数据已被情况,所以在从库你看到的是过期数据。

重启后,主从库如何同步内存表数据?

当主库使用内存表,主库启动后,一条DELETE语句会写入到主库的binary log中,从库接到命令后清空内存表。

主库重启期间,从库还是有读取到过期数据的情况。为了避免这种情况,主库启动时加入--init-file参数,这样主库启动自动将数据加载到内存表中。(官方文档写的不严谨,我认为仅限于内存表只读场景。如果不是只读,即使加入--init-file参数也无法保证主库内存表数据一致)。

管理内存使用情况

服务器必须有足够内存,来满足多张内存表的使用。

如果从内存表中删除单独的行,并不会回收内存。当整个内存表删除时,才回收内存。同一张内存表,之前删除行占用的空间,会被新的行复用。执行DELETE、TRUNCATE TABLE来释放内存表占用空间,如果表不在使用可使用DROP TABLE命令。释放正在使用的内存表占用的内存,可以使用 ALTER TABLE XX ENGINE=MEMORY 强制重建表。

内存表1行记录占用内存计算公式

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 的大小,否则所有会话的内存表较大尺寸都为该值 )。

下面的例子创建了2个内存表,较大尺寸为1M和2M

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 变量的值大小。

压测结果

通过sysbench压测,InnoDB 写性能完爆MEMORY引擎,MEMORY的读性能略高于InnoDB。InnoDB的综合性能更好,足够满足日常使用。考虑到MEMORY引擎的雷点太多,建议不使用MEMORY引擎。

文章来源:chinaunix

《MySQL DBA从小白到大神实战》课程实战到底,从操作中明白原理,从原理中清楚操作,让各位童鞋真正的有收获和彻底消化理解并将其变成自己的技能。返回搜狐,查看更多

责任编辑:

mysql memory_MySQL MEMORY 引擎及性能比对相关推荐

  1. MySQL常用存储引擎之Memory

    看一下MYSQL存储引擎的Memory存储引擎,Memory存储引擎也称之为HEAP存储引擎,从这个存储引擎的名字中呢,可以知道,所有的数据都保存在内存中的,这就意味着呢,这种存储引擎表的数据呢,一旦 ...

  2. mysql实战38 | 都说InnoDB好,那还要不要使用Memory引擎?

    我在上一篇文章末尾留给你的问题是:两个 group by 语句都用了 order by null,为什么使用内存临时表得到的语句结果里,0 这个值在最后一行:而使用磁盘临时表得到的结果里,0 这个值在 ...

  3. MySQL 的三大引擎:InnoDB、MyISAM和Memory

    http://www.cnblogs.com/kakaliush/archive/2010/02/23/1671757.html MySQL的三大引擎:InnoDB.MyISAM和Memory Inn ...

  4. 【MySQL】MySQL的存储引擎和索引详解(聚集索引和非聚集索引)

    目录 一.MySQL存储引擎 1.1  Innodb引擎 1.2 MyISAM引擎 1.3 InNoDB与MyISAM异同 1.4 两种引擎的选择 二.索引(Index) 2.1 InnoDB存储引擎 ...

  5. mysql的存储引擎种类,mysql 存储引擎,基本数据类型

    存储引擎 日常生活中文件格式有很多种,并且针对不同的文件格式会有对应不同存储方式和处理机制(txt,pdf, word, mp4...) 针对不同的数据应该有对应的不同的处理机制来存储 存储引擎就是不 ...

  6. mysql支持的并发数_重学MySQL系列(五):谈谈对MySQL的存储引擎的理解

    原创作者,公众号[程序员读书],欢迎关注公众号,转载文章请注明出处哦. MySQL关于存储引擎的架构设计,相较于其他关系数据库管理系统,比如Oracle,SQL Server等数据库,这是MySQL最 ...

  7. unicode表_Python数据库操作 Mysql数据库表引擎与字符集#学习猿地

    # Mysql数据库表引擎与字符集 ![](./imgs/752951346A5F4E7EBDE362FA97107707.png) ### 1.服务器处理客户端请求 其实不论客户端进程和服务器进程是 ...

  8. mysql的三大引擎是什么_MySQL常用三大存储引擎

    MySQL 常用存储引擎 存储引擎是数据库的核心,对于mysql来说,存储引擎是以插件的形式运行的,默认是InnoDB. 1. MyISAM 使用这个存储引擎,每个MyISAM在磁盘上存储成三个文件. ...

  9. Mysql 索引 总结 —— 概述 || 索引优势劣势|| 索引结构(索引是在MySQL的存储引擎层中实现的)|| BTREE 结构||B+TREE 结构||MySQL中的B+Tree||索引分类

    索引概述 MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构(有序). 在数据之外,数据库系统还维护者满足特定查找算法的数据结构, 这些数据结构以某种方式引用(指向 ...

最新文章

  1. MySQL使用可重复读作为默认隔离级别的原因
  2. 【性能优化】 之 10053 事件
  3. 下载旧版本jdk和tomcat
  4. python处理era5_ERA5数据python批量下载程序
  5. hadoop yarn 获取日志_「大数据」「Hadoop」-安装及数据目录
  6. cadence入门学习
  7. Appium环境搭建超详细教程
  8. 深度学习——AI领域会议列表(以备准备和更新论文存储使用)
  9. java群面自我介绍,群面的一分钟自我介绍
  10. Greasy Fork、GitHub、OpenUserJS
  11. android百度天气接口api接口,百度天气接口api
  12. printf输出bool值 | printf转换符
  13. C语言写出一个随机生成1-100数字的猜数字游戏
  14. Android 自动抓取网站图标实现分享样式的定制
  15. Hive UDF自定义函数(临时和永久的区别)
  16. 计算机桌面显示左右有黑边,电脑屏幕显示不全左右两边黑边框 win7电脑屏幕边缘显示不全怎么调整...
  17. 好几天忘记笑了~2012年9月10日
  18. linux如何定位内存泄漏,快速定位内存泄漏的套路(linux)
  19. 棒棒糖c语言编译器,用C语言画个棒棒糖-一言不合就分享!代!码
  20. (五)汇编实现流水灯

热门文章

  1. 08-GCD常用方法
  2. 二分搜索 POJ 3273 Monthly Expense
  3. 老男孩为网友工作疑难问题解答一例
  4. Linux下挂载存储设备
  5. 【转载】 regsvr32 注册dll
  6. Linux System and Performance Monitoring
  7. 在ASP.NET中UrlRewrite的实现(能隐藏扩展名)之一
  8. 我们的2008。。。。。。
  9. 测试香港服务器访问速度的方法
  10. Tomcat项目部署