今天遇到一个很棘手的问题,想临时存起来一部分数据,而后再读取。我记得学数据库理论课老师说能够建立临时表,不知道mysql有没有这样的功能呢?临时表在内存之中,读取速度应该比视图快一些。而后还须要将查询的结果存储到临时表中。下面是建立临时表以及插入数据的例子,以供你们参考。html
A、临时表再断开于mysql的链接后系统会自动删除临时表中的数据,可是这只限于用下面语句创建的表:
1)定义字段
CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
time date NOT NULL
)
更高级点就是:
create temporary TABLE `temtable` (
`jws` varchar(100) character set utf8 collate utf8_bin NOT NULL,
`tzlb` varchar(100) character set utf8 collate utf8_bin NOT NULL,
`uptime` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1″
连编码方式都规定了。。呵呵,以防乱码啊。mysql
2)直接将查询结果导入临时表
CREATE TEMPORARY TABLE tmp_table SELECT * FROM table_namesql
B、另外mysql也容许你在内存中直接建立临时表,由于是在内存中全部速度会很快,语法以下:
CREATE TEMPORARY TABLE tmp_table (
name VARCHAR(10) NOT NULL,
value INTEGER NOT NULL
) TYPE = HEAP数据库
那如何将查询的结果存入已有的表呢?服务器
一、可使用A中第二个方法函数
二、使用insert into temtable (select a,b,c,d from tablea)”;性能
首先,临时表只在当前链接可见,当关闭链接时,Mysql会自动删除表并释放全部空间。所以在不一样的链接中能够建立同名的临时表,而且操做属于本链接的临时表。大数据
建立临时表的语法与建立表语法相似,不一样之处是增长关键字TEMPORARY,如:ui
CREATE TEMPORARY TABLE 表名 (…. )编码
临时表使用有一些限制条件:
* 临时表在 memory、myisam、merge或者innodb上使用,而且不支持mysql cluster簇);
show tables语句不会列出临时表,在information_schema中也不存在临时表信息;show create table能够查看临时表;
* 不能使用rename来重命名临时表。可是能够alter table rename代替:
mysql>ALTER TABLE orig_name RENAME new_name;
* 能够复制临时表获得一个新的临时表,如:
mysql>create temporary table new_table select * from old_table;
* 但在同一个query语句中,相同的临时表只能出现一次。如:
可使用:mysql> select * from temp_tb;
但不能使用:mysql> select * from temp_tb, temp_tb as t;
错误信息: ERROR 1137 (HY000): Can't reopen table: 'temp_tb'
一样相同临时表不能在存储函数中出现屡次,若是在一个存储函数里,用不一样的别名查找一个临时表屡次,或者在这个存储函数里用不一样的语句查找,都会出现这个错误。
* 但不一样的临时表能够出如今同一个query语句中,如临时表temp_tb1, temp_tb2:
Mysql> select * from temp_tb1, temp_tb2;
临时表能够手动删除:
DROP TEMPORARY TABLE IF EXISTS temp_tb;
临时表主要用于对大数据量的表上做一个子集,提升查询效率。
在建立临时表时声明类型为HEAP,则Mysql会在内存中建立该临时表,即内存表:如:
CREATE TEMPORARY TABLE 表名 (。。。。) TYPE = HEAP
由于HEAP表存储在内存中,你对它运行的查询可能比磁盘上的临时表快些。如:
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服务器使用内部临时表
在某些状况下,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字节的
MySQL如何使用临时表??
【临时表存储】
MySQL临时表分为“内存临时表”和“磁盘临时表”,其中内存临时表使用MySQL的MEMORY存储引擎,磁盘临时表使用MySQL的MyISAM存储引擎;
通常状况下,MySQL会先建立内存临时表,但内存临时表超过配置指定的值后,MySQL会将内存临时表导出到磁盘临时表。
【使用临时表的场景】
1)ORDER BY子句和GROUP BY子句不一样,
例如:ORDERY BY price GROUP BY name;
2)在JOIN查询中,ORDER BY或者GROUP BY使用了不是第一个表的列
例如:SELECT * from TableA, TableB ORDER BY TableA.price GROUP by TableB.name
3)ORDER BY中使用了DISTINCT关键字
ORDERY BY DISTINCT(price)
4)SELECT语句中指定了SQL_SMALL_RESULT关键字
SQL_SMALL_RESULT的意思就是告诉MySQL,结果会很小,请直接使用内存临时表,不须要使用索引排序
SQL_SMALL_RESULT必须和GROUP BY、DISTINCT或DISTINCTROW一块儿使用
通常状况下,咱们没有必要使用这个选项,让MySQL服务器选择便可。
【直接使用磁盘临时表的场景】
1)表包含TEXT或者BLOB列;
2)GROUP BY 或者 DISTINCT 子句中包含长度大于512字节的列;
3)使用UNION或者UNION ALL时,SELECT子句中包含大于512字节的列;
【临时表相关配置】
tmp_table_size:指定系统建立的内存临时表最大大小;
http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_tmp_table_size
max_heap_table_size: 指定用户建立的内存表的最大大小;
http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_max_heap_table_size
注意:最终的系统建立的内存临时表大小是取上述两个配置值的最小值。
【表的设计原则】
使用临时表通常都意味着性能比较低,特别是使用磁盘临时表,性能更慢,所以咱们在实际应用中应该尽可能避免临时表的使用。
若是实在没法避免,也应该尽可能避免使用磁盘临时表。
常见的方法有:
1)建立索引:在ORDER BY或者GROUP BY的列上建立索引,这样能够避免使用临时表;
2)分拆很长的列,能够避免使用磁盘临时表:通常状况下,TEXT、BLOB,大于512字节的字符串,基本上都是为了显示信息,而不会用于查询条件,所以表设计的时候,应该将这些列独立到另一张表。
【如何判断使用了临时表?】
使用explain查看执行计划,Extra列看到Using temporary就意味着使用了临时表。
MySQL官方手册:
http://dev.mysql.com/doc/refman/5.1/en/internal-temporary-tables.html