session 1
$ mysql -uroot
root@(none) 10:05:06>use test
Database changed
root@test 10:06:06>CREATE TABLE tmp_memory (i INT) ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)
root@test 10:08:46>insert into tmp_memory values (1);
Query OK, 1 row affected (0.00 sec)
root@test 10:08:46>
session2
$ mysql -uroot test
root@test 10:05:12>CREATE TABLE tmp_memory (i INT) ENGINE = MEMORY;
ERROR 1050 (42S01): Table 'tmp_memory' already exists
root@test 10:16:27>select * from tmp_memory;
+------+
| i |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
多个session,创建表的名字不能一样
一个session创建会话后,对其他session也是可见的
session1
$ mysql -uroot test
root@test 10:30:18>CREATE TEMPORARY TABLE tmp_table (name VARCHAR(10) NOT NULL,value INTEGER NOT NULL);
Query OK, 0 rows affected (0.05 sec)
root@test 10:31:54>select * from tmp_table;
+--------+-------+
| name | value |
+--------+-------+
| aaaaaa | 10 |
+--------+-------+
1 row in set (0.00 sec)
session2
root@test 10:20:13> CREATE TEMPORARY TABLE tmp_table (name VARCHAR(10) NOT NULL,value INTEGER NOT NULL);
Query OK, 0 rows affected (0.02 sec)
root@test 10:30:39>insert into tmp_table values ('bbbbbbb',10);
Query OK, 1 row affected (0.01 sec)
root@test 10:31:33>select * from tmp_table;
+---------+-------+
| name | value |
+---------+-------+
| bbbbbbb | 10 |
+---------+-------+
1 row in set (0.00 sec)
root@test 10:31:43>exit
Bye
[1 Single:MS-Master db152011.sqa.cm6: mysql ~ ]
$ mysql -uroot test
root@test 10:32:17>select * from tmp_table;
ERROR 1146 (42S02): Table 'test.tmp_table' doesn't exist
root@test 10:32:22>
root@test 10:32:23>
创建的表的名字可以一样
表结构和数据都放在内存中
内存表需要自己delete数据或者drop表;需要drop权限,这点比较危险
内存表的表结构是保存在磁盘上的,如果多个session使用同一个表名,会存在冲突;如果不需要使用表名,如果使用一次都需要创建表结构,到时候会有很多小文件存在,不利于db的维护,dba清理表也有风险;
临时表是会话级别的,即使多个session创建的表名一样,都相互不影响
会话消失,所有的都消失,这点很不利于应用排查问题
另外这两个都需要消耗额外的内存空间,虽然db端可以忍受,但是不太可控;DB端还有这个参数:
max_tmp_tables 一个客户能同时保持打开的临时表的最大数量,这个值默认32,可以根据需要调整此值
首先,临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间。因此在不同的连接中可以创建同名的临时表,并且操作属于本连接的临时表。
创建临时表的语法与创建表语法类似,不同之处是增加关键字TEMPORARY,如:
CREATE TEMPORARY TABLE 表名 (…. )
临时表可以手动删除:
DROP TEMPORARY TABLE IF EXISTS temp_tb;
临时表主要用于对大数据量的表上作一个子集,提高查询效率。
mysql> 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指定:
[mysqld]
max_heap_table_size=1024M #内存表容量
tmp_table_size=1024M #临时表容量
当数据超过临时表的最大值设定时,自动转为磁盘表,此时因需要进行IO操作,性能会大大下降,而内存表不会,内存表满后,则会提示数据满错误。
show tables 命令不会显示临时表。
内存表:
1.缺省存储引擎为MEMORY
2.可以通过参数max_heap_table_size来设定内存表大小
3.到达max_heap_table_size设定的内存上限后将报错
4.表定义保存在磁盘上,数据和索引保存在内存中
5.不能包含TEXT、BLOB等字段
临时表:
1.缺省存储引擎为MySQL服务器默认引擎,引擎类型只能是:memory(heap)、myisam、merge、innodb(memory临时表由于表的增大可能会转变为myisam临时表)
2.可以通过参数 tmp_table_size 来设定临时表大小。
3.到达tmp_table_size设定的内存上限后将在磁盘上创建临时文件
4.表定义和数据都保存在内存中
5.可以包含TEXT, BLOB等字段
临时表一般比较少用,通常是在应用程序中动态创建或者由MySQL内部根据SQL执行计划需要自己创建。
内存表则大多作为Cache来使用,特别在没有第三方cache使用时。如今随着memcache、NoSQL的流行,越来越少选择使用内存表。
在某些情况下,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字节的
转载自:http://www.cnblogs.com/jevo/p/3262227.html
http://www.cnblogs.com/sunss/archive/2013/07/15/3191137.html
http://javaeye-mao.iteye.com/blog/1511385(临时表在不同数据库设计中的作用)
http://javaman.group.iteye.com/group/wiki/3430-mysql-memory-table-temp(实验)
http://www.cnblogs.com/kissdodog/archive/2013/07/03/3169470.html(SQL Server 表变量和临时表的区别)