首先,临时表只在当前连接可见,当关闭连接时,MySQL会自动删除表并释放所有空间。因此在不同的连接中可以创建同名的临时表,并且操作属于本连接的临时表。创建临时表的语法与创建表语法类似,不同之处是增加关键字TEMPORARY。1
CREATE TEMPORARY TABLE 表名 (…)
临时表
限制条件
临时表在memory
、myisam
、merge
或者innodb
上使用,并且不支持mysql cluster
。show tables
语句不会列出临时表,在information_schema
中也不存在临时表信息;show create table
可以查看临时表。
不能使用rename
来重命名临时表。但是可以alter table rename
代替。1
mysql>ALTER TABLE orig_name RENAME new_name;
可以复制临时表得到一个新的临时表。1
mysql>create temporary table new_table select * from old_table;
但在同一个query语句中,相同的临时表只能出现一次。
正确1
mysql> select * from temp_tb;
错误1
2
3mysql> select * from temp_tb, temp_tb as t;
ERROR 1137 (HY000): Can't reopen table: 'temp_tb'
同样相同临时表不能在存储函数中出现多次,如果在一个存储函数里,用不同的别名查找一个临时表多次,或者在这个存储函数里用不同的语句查找,都会出现这个错误。
但不同的临时表可以出现在同一个query语句中,如临时表temp_tb1, temp_tb2。1
Mysql> select * from temp_tb1, temp_tb2;
临时表可以手动删除。1
DROP TEMPORARY TABLE IF EXISTS temp_tb;
内存表
临时表主要用于对大数据量的表上作一个子集,提高查询效率。
在创建临时表时声明类型为HEAP,则MySQL会在内存中创建该临时表,即内存表。1
CREATE TEMPORARY TABLE 表名 (....) TYPE = HEAP
因为HEAP
表存储在内存中,你对它运行的查询可能比磁盘上的临时表快些。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16mysql> create temporary table temp_tb type='heap' select * from temptb;
Query OK, 0 rows affected, 1 warning (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table temp_tb \G;
*************************** 1. row ***************************
Table: temp_tb
Create Table: CREATE TEMPORARY TABLE `temp_tb` (
`id` int(10) unsigned NOT NULL DEFAULT '0',
`Name` char(20) NOT NULL,
`Age` tinyint(4) NOT NULL
) ENGINE=MEMORY DEFAULT CHARSET=gbk
1 row in set (0.00 sec)
ERROR:
No query specified
可以看出来临时表和内存表的ENGINE不同,临时表默认的是MySQL指定的默认Engine,而内存表是MEMORY。
官网手册
As indicated by the name, MEMORY tables are stored in memory. They use hash indexes by default, which makes them very fast, and very useful for creating temporary tables. However, when the server shuts down, all rows stored in MEMORY tables are lost. The tables themselves continue to exist because their definitions are stored in .frm files on disk, but they are empty when the server restarts.
限制条件
MEMORY tables cannot contain BLOB or TEXT columns.
HEAP不支持BLOB/TEXT列。
The server needs sufficient memory to maintain all MEMORY tables that are in use at the same time.
在同一时间需要足够的内存。
To free memory used by a MEMORY table when you no longer require its contents, you should execute DELETE or TRUNCATE TABLE, or remove the table altogether using DROP TABLE.
为了释放内存,你应该执行DELETE FROM heap_table
或DROP TABLE heap_table
。
临时表和内存表
临时表主要是为了放一些中间大结果集的一些子集,内存表可以放一些经常频繁使用的数据。
临时表
表建在内存里,数据在内存里。
内存表
表建在磁盘里,数据在内存里。
临时表和内存表所使用内存大小可以通过My.cnf
中的max_heap_table_size
、tmp_table_size
指定。1
2
3[mysqld]
max_heap_table_size=1024M #内存表容量
tmp_table_size=1024M #临时表容量
当数据超过临时表的最大值设定时,自动转为磁盘表,此时因需要进行IO操作,性能会大大下降,而内存表不会,内存表满后,则会提示数据满错误。show tables
命令不会显示临时表。
内存表和临时表区别
内存表
- 缺省存储引擎为MEMORY。
- 可以通过参数
max_heap_table_size
来设定内存表大小。 - 到达
max_heap_table_size
设定的内存上限后将报错。 - 表定义保存在磁盘上,数据和索引保存在内存中。
- 不能包含TEXT、BLOB等字段。
临时表:
- 缺省存储引擎为MySQL服务器默认引擎,引擎类型只能是:
memory
(heap)、myisam
、merge
、innodb
(memory
临时表由于表的增大可能会转变为myisam
临时表) - 可以通过参数
tmp_table_size
来设定临时表大小。 - 到达
tmp_table_size
设定的内存上限后将在磁盘上创建临时文件。 - 表定义和数据都保存在内存中。
- 可以包含TEXT, BLOB等字段。
临时表一般比较少用,通常是在应用程序中动态创建或者由MySQL内部根据SQL执行计划需要自己创建。
内存表则大多作为Cache来使用,特别在没有第三方cache使用时。如今随着memcache、NoSQL的流行,越来越少选择使用内存表。
MySQL服务器使用内部临时表。
在某些情况下,MySQL服务器会自动创建内部临时表。查看查询语句的执行计划,如果extra列显示using temporary
即使用了内部临时表。内部临时表的创建条件。
group by
和order by
中的列不相同。order by
的列不是引用from表列表中的第一表。group by
的列不是引用from表列表中的第一表。- 使用
sql_small_result
选项。 - 含有
distinct
的order by
语句。
初始创建内部myisam
临时表的条件。
- 表中存在text、blob列。
- 在
group by
中的列有超过512字节。 - 在
distinct
查询中的 列 有超过512字节。 - 在
union
、union all
联合查询中,select
列列表中的列有超过512字节的。
什么时候使用视图
应用场景1
保密工作,比如有一个员工工资表,如果你只希望财务看到员工工资这个字段,而其他人不能看到工资字段,那就用一个视图,把工资这个敏感字段过滤掉
应用场景2
有一个查询语句非常复杂,大概有100行这么多,有时还想把这个巨大无比的select语句和其他表关联起来得到结果,写太多很麻烦,可以用一个视图来代替这100行的select语句,充当一个变量角色
什么时候用临时表
应用场景1
你在短期内有很多DML操作,比如京东淘宝亚马逊的购物车表,把东西放购物车(insert),变更数量(update),删除商品(delete),一旦结算金钱后,这些数据就要清掉,这时需要用临时表。
应用场景2
在导出数据时,你可能不想导完整的数据库,或者表,你可能只想要导出符合某些条件的数据,那么你可以创建临时表,把select语句插入到临时表,接着导出这个临时表,导完以后通过结束session或者事务的方式,让这些没用的数据自动清理掉。
应用场景3
你在写存储过程时,有很多的连接,比如你需要连接A,B,C,D,E,F,G,H那么多张表,才能得到你的结果表,同时做连接的消耗太大,你可以先A,B,C连接的结果,放在临时表,接着再把这张临时表,跟D,E,F连接,作为新的结果放在临时表,接着再把临时表与G,H连接,最后得到临时表数据,一次插入到结果表(永久表)。