MySQL 内存表和临时表有什么区别呢?你知道吗?

分享一道京东面试题:MySQL 内存表和临时表有什么区别呢?

1.概念

临时表用来给复杂查询保存中间结果,分为内部临时表和外部临时表。

内部临时表:MySQL 内部生成,比如 union 语句、group by 语句可以保存中间结果;外部临时表:由客户端创建,SQL 语法:CREATE TEMPORARY TABLE。

内存表是指使用 Memory 存储引擎的表,创建语句如下:

复制
create table test_memory(`id` int, `a` VARCHAR(20) DEFAULT NULL, PRIMARY KEY (`id`)) engine=Memory;1.

内存表可以给所有客户端看到,客户端连接关闭后不影响内存表。但如果 MySQL 重启服务,内存表的数据会丢失,表结构还在。

可以看到,临时表也可以是内存表。

2.生命周期

临时表是会话级别的,客户端连接关闭后,临时表自动删除。同时,会话之间的临时表是相互隔离的,不同会话可以创建相同名称的临时表。

内存表则不受会话的影响,只有使用 drop 才能删除掉。

3.存储

临时表可以使用各种存储引擎,比如 InnoDB、MyISAM 或者 MEMORY。创建时使用 ENGINE = xxx 来指定。如果临时表使用的存储引擎是 MEMORY(内存临时表),则会受下面参数限制:

tmp_table_size:临时表的最大内存值;max_heap_table_size:临时表的最大堆内存值,主要用来计算临时表的最大行数。

内存临时表的内存不能超过上面两个参数最小值的,如果超出,则会转化成磁盘临时表,查询效率下降。

内存表的数据存储在内存中。如果服务重启,或者内存不足,数据会丢失。

4.索引方式

内存表默认使用 hash 索引,不支持范围扫描或排序。

临时表则根据选择的存储引擎,支持的索引类型不同。如果选择 Innodb,则支持 B+ 树索引,支持事务,支持行级锁。

5.使用场景

内存表主要用于数据量较小、需要快速访问、允许数据丢失的场景。

临时表则用于单个会话中需要保存临时结果,会话结束可以自动清理的场景。比如 union、group by 语句。

下面看一下 union 语句执行过程,测试 SQL 如下: 先创建两个表:

复制
CREATE TABLE test_temp1(`id` INT, `a` VARCHAR(20) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=INNODB; CREATE TABLE test_temp2(`id` INT, `a` VARCHAR(20) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=INNODB;1.2.

然后执行查询语句:

复制
SELECT * FROM test_temp1 UNION SELECT * FROM test_temp2;1.

从执行计划 Extra 可以看出,查询语句用到了临时表。

图片

这个语句执行过程如下:

创建一个内存临时表,这个临时表有 2 个字段,id 和 a,其中 id 为主键;执行第一个子查询,获取 test_temp1 的所有记录,放到临时表中;执行第二个子查询,获取 test_temp2 表的所有记录,依次插入临时表中,如果有主键冲突,则失败,继续插入下一条;将临时表中数据作为结果集返回;删除临时表。

6.总结

下面总结内存表和临时表的区别:

特性

内存表

临时表

存储引擎

Memory

可以选择 Memory、InnoDB、MyISAM

生命周期

表结构持久化,不重启服务,数据不会丢失

会话结束,删除表

索引方式

默认hash索引

根据存储引擎支持不同类型

使用场景

数据量较小、需要快速访问、允许数据丢失

保存临时结果

阅读剩余
THE END