MySQL临时表

MySQL临时表

 




 

MySQL 临时表

MySQL 临时表在咱们须要保存一些临时数据时是很是有用的。临时表只在当前链接可见,当关闭链接时,Mysql会自动删除表并释放全部空间。 html

临时表在MySQL 3.23版本中添加,若是你的MySQL版本低于 3.23版本就没法使用MySQL的临时表。不过如今通常不多有再使用这么低版本的MySQL数据库服务了。 java

MySQL临时表只在当前链接可见,若是你使用PHP脚原本建立MySQL临时表,那每当PHP脚本执行完成后,该临时表也会自动销毁。 mysql

若是你使用了其余MySQL客户端程序链接MySQL数据库服务器来建立临时表,那么只有在关闭客户端程序时才会销毁临时表,固然你也能够手动销毁。 面试

实例

如下展现了使用MySQL 临时表的简单实例,如下的SQL代码能够适用于PHP脚本的mysql_query()函数。 sql

>mysql> CREATE TEMPORARY TABLE SalesSummary (
    -> product_name VARCHAR(50) NOT NULL
    -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
    -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
    -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)


mysql> INSERT INTO SalesSummary
    -> (product_name, total_sales, avg_unit_price, total_units_sold)
    -> VALUES
    -> ('cucumber', 100.25, 90, 2);


mysql> SELECT * FROM SalesSummary;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)

 

当你使用 SHOW TABLES命令显示数据表列表时,你将没法看到 SalesSummary表。 数据库

若是你退出当前MySQL会话,再使用 SELECT命令来读取原先建立的临时表数据,那你会发现数据库中没有该表的存在,由于在你退出时该临时表已经被销毁了。 数组


删除MySQL 临时表

默认状况下,当你断开与数据库的链接后,临时表就会自动被销毁。固然你也能够在当前MySQL会话使用 DROP TABLE 命令来手动删除临时表。 性能优化

如下是手动删除临时表的实例: 服务器

mysql> CREATE TEMPORARY TABLE SalesSummary (
    -> product_name VARCHAR(50) NOT NULL
    -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
    -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
    -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)


mysql> INSERT INTO SalesSummary
    -> (product_name, total_sales, avg_unit_price, total_units_sold)
    -> VALUES
    -> ('cucumber', 100.25, 90, 2);


mysql> SELECT * FROM SalesSummary;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)
mysql> DROP TABLE SalesSummary;
mysql>  SELECT * FROM SalesSummary;
ERROR 1146: Table 'RUNOOB.SalesSummary' doesn't exist

 


 

MySQL中临时表的基本建立与使用教程

当工做在很是大的表上时,你可能偶尔须要运行不少查询得到一个大量数据的小的子集,不是对整个表运行这些查询,而是让MySQL每次找出所需的少数记录,将记录选择到一个临时表可能更快些,而后在这些表运行查询。微信

建立临时表很容易,给正常的CREATE TABLE语句加上TEMPORARY关键字:

CREATE TEMPORARY TABLE tmp_table (
 name VARCHAR(10) NOT NULL,
 value INTEGER NOT NULL
)

 

临时表将在你链接MySQL期间存在。当你断开时,MySQL将自动删除表并释放所用的空间。固然你能够在仍然链接的时候删除表并释放空间。

DROP TABLE tmp_table

 

若是在你建立名为tmp_table临时表时名为tmp_table的表在数据库中已经存在,临时表将有必要屏蔽(隐藏)非临时表tmp_table。

若是你声明临时表是一个HEAP表,MySQL也容许你指定在内存中建立它:

CREATE TEMPORARY TABLE tmp_table (  
 name VARCHAR(10) NOT NULL,
 value INTEGER NOT NULL
) TYPE = HEAP

 

由于HEAP表存储在内存中,你对它运行的查询可能比磁盘上的临时表快些。然而,HEAP表与通常的表有些不一样,且有自身的限制。详见MySQL参考手册。

正如前面的建议,你应该测试临时表看看它们是否真的比对大量数据库运行查询快。若是数据很好地索引,临时表可能一点不快。

临时表再断开于mysql的链接后系统会自动删除临时表中的数据,可是这只限于用下面语句创建的表:

定义字段:

CREATE TEMPORARY TABLE tmp_table (
 name VARCHAR(10) NOT NULL,
 value INTEGER NOT NULL 
)

 

直接将查询结果导入临时表

CREATE TEMPORARY TABLE tmp_table SELECT * FROM table_name

 

另外mysql也容许你在内存中直接建立临时表,由于是在内存中全部速度会很快,语法以下:

CREATE TEMPORARY TABLE tmp_table (
 name VARCHAR(10) NOT NULL,
 value INTEGER NOT NULL
) TYPE = HEAP

 

 从上面的分析能够看出临时表的数据是会被清空的,你断开了链接就会被自动清空,可是你程序中不可能每发行一次sql就链接一次数据库吧(若是是这样的话,那就会出现你担忧的问题,若是不是就没有问题),由于只有断开数据库链接才会被清空数据,在一个数据库链接里面发行屡次sql的话系统是不会自动清空临时表数据的。

只有在当前链接状况下, TEMPORARY 表才是可见的。当链接关闭时, TEMPORARY 表被自动取消。这意味着两个不一样的链接可使用相同的临时表名称,同时两个临时表不会互相冲突,也不与原有的同名的非临时表冲突。(原有的表被隐藏,直到临时表被取消时为止。)必须拥有 CREATE TEMPORARY TABLES 权限,才能建立临时表。能够经过指定 ENGINE|TYPE = MEMORY; 来指定建立内存临时表。

若是表已存在,则使用关键词 IF NOT EXISTS 能够防止发生错误。注意,原有表的结构与 CREATE TABLE 语句中表示的表的结构是否相同,这一点没有验证。注释:若是在 CREATE TABLE...SELECT 语句中使用 IF NOT EXISTS ,则不论表是否已存在,由 SELECT 部分选择的记录都会被插入。

DROP TEMPORARY TABLE 语句只取消 TEMPORARY 表,语句不会终止正在进行中的事务。在采用链接池的状况下,为防止屡次 CREATE 、 DROP TEMPORARY TABLE 带来的性能瓶颈,可使用 CREATE IF NOT EXISTS + TRUNCATE TABLE 的方式来提高性能。

临时表支持主键、索引指定。在链接非临时表查询能够利用指定主键或索引来提高性能。

CREATE PROCEDURE sp_test_tt(IN i_chars VARCHAR(50),OUT o_counts BIGINT)
BEGIN
     create temporary table if not exists tmpTable – 不存在则建立临时表
     (
      objChk varchar(255) primary key,
      ModelName varchar(50),
      Operator varchar(500),
      PModelName varchar(50)
     );
     truncate TABLE tmpTable; -- 使用前先清空临时表。
 
     insert into tmpTable values(i_chars,i_chars,i_chars,i_chars);
     insert into tmpTable values(i_chars,i_chars,i_chars,i_chars); -- 语句1
     select * from tmpTable; -- 语句2
     select count(*) into o_counts from tmpTable; -- 语句3
END;

 

上述代码语句 1 返回临时表中全部数据,语句 2 将总记录数写入输出参数。 truncate 语句放在 create 以后,而不是整个存储过程最后,缘由在于随后的语句 1 插入一样的值,二临时表 PK 校验将产生一个错误,则存储过程最终异常结束。综合异常处理,能够以下修改,以在每次存储过程调用完毕后清除临时表。
再来看一个例子:

CREATE PROCEDURE sp_test_tt(IN i_chars VARCHAR(50),OUT o_counts BIGINT)
BEGIN
     create temporary table if not exists tmpTable
     (
      objChk varchar(255) primary key,
      ModelName varchar(50),
      Operator varchar(500),
      PModelName varchar(50)
     ) ENGINE = MEMORY;
     begin
          declare exit handler for sqlwarning,NOT FOUND,SQLEXCEPTION set o_counts=-1;
          insert into tmpTable values(i_chars,i_chars,i_chars,i_chars);
          select * from tmpTable; -- 语句1
          select count(*) into o_counts from tmpTable;
     end;
     truncate TABLE tmpTable; -- 语句2
END;

 

虽然上述代码语句 2 最后 truncate table 清空了所有临时表数据,但前面语句 1 select 的数据结果集不会被清除。已经过 java 程序验证。

临时表能够解决二维数组输出的问题。可是,大批量的数据插入只能由程序采用循环来作。某些特殊状况下的输入数组,例如选择好的一组待删除数据的 ID 的输入,也只能利用循环来作。临时表也不适用于须要三维数组的状况。



经过CREATE TEMPORARY TABLE 建立的临时表,这种临时表称为外部临时表。这种临时表只对当前用户可见,当前会话结束的时候,该临时表会自动关闭。这种临时表的命名与非临时表能够同名(同名后非临时表将对当前会话不可见,直到临时表被删除)。

内部临时表

内部临时表是一种特殊轻量级的临时表,用来进行性能优化。这种临时表会被MySQL自动建立并用来存储某些操做的中间结果。这些操做可能包括在优化阶段或者执行阶段。这种内部表对用户来讲是不可见的,可是经过EXPLAIN或者SHOW STATUS能够查看MYSQL是否使用了内部临时表用来帮助完成某个操做。内部临时表在SQL语句的优化过程当中扮演着很是重要的角色, MySQL中的不少操做都要依赖于内部临时表来进行优化。可是使用内部临时表须要建立表以及中间数据的存取代价,因此用户在写SQL语句的时候应该尽可能的去避免使用临时表。

内部临时表有两种类型:一种是HEAP临时表,这种临时表的全部数据都会存在内存中,对于这种表的操做不须要IO操做。另外一种是OnDisk临时表,顾名思义,这种临时表会将数据存储在磁盘上。OnDisk临时表用来处理中间结果比较大的操做。若是HEAP临时表存储的数据大于MAX_HEAP_TABLE_SIZE(详情请参考MySQL手册中系统变量部分),HEAP临时表将会被自动转换成OnDisk临时表。OnDisk临时表在5.7中能够经过INTERNAL_TMP_DISK_STORAGE_ENGINE系统变量选择使用MyISAM引擎或者InnoDB引擎。



mysql的内存表和临时表

内存表:

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 |      
+------+      
row in set (0.00 sec)      

1. 多个session,建立表的名字不能同样

2. 一个session建立会话后,对其余session也是可见的
3. data目录下只有tmp_memory.frm ,表结构放在磁盘上,数据放在内存中
4. mysql 重启或者关闭后内存表里的数据会丢失,可是表结构仍然存在
5. 能够建立索引,删除索引,支持惟一索引
6. 不影响主备,主库上插入的数据,备库也能够查到
7. show tables 看获得表

临时表:

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 |      
+--------+-------+      
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 |      
+---------+-------+      
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>      

1. 建立的表的名字能够同样 

2. 表结构和数据都放在内存中
3. 会话消失表结构和数据都消失
4. 能够建立索引,删除索引
5. 主库建立的表,备库查不到,
6. show tables 看不到表

使用内存表须要注意的事项

1. 内存表须要本身delete数据或者drop表;须要drop权限,这点比较危险

2. 内存表的表结构是保存在磁盘上的,若是多个session使用同一个表名,会存在冲突;若是不须要使用表名,若是使用一次都须要建立表结构,到时候会有不少小文件存在,不利于db的维护,dba清理表也有风险;

基于以上不适合用内存表

1. 临时表是会话级别的,即便多个session建立的表名同样,都相互不影响

2. 会话消失,全部的都消失,这点很不利于应用排查问题

另外这两个都须要消耗额外的内存空间,虽然db端能够忍受,可是不太可控;DB端还有这个参数:

max_tmp_tables 一个客户能同时保持打开的临时表的最大数量,这个值默认32,能够根据须要调整此值


 
 
 
 





About Me

.............................................................................................................................................

● 本文做者:小麦苗,部份内容整理自网络,如有侵权请联系小麦苗删除

● 本文在itpub(http://blog.itpub.net/26736162/abstract/1/)、博客园(http://www.cnblogs.com/lhrbest)和我的微信公众号(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/

● 本文博客园地址:http://www.cnblogs.com/lhrbest

● 本文pdf版、我的简介及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/

● 数据库笔试面试题库及解答:http://blog.itpub.net/26736162/viewspace-2134706/

● DBA宝典今日头条号地址:http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

.............................................................................................................................................

● QQ群号:230161599(满)、618766405

● 微信群:可加我微信,我拉你们进群,非诚勿扰

● 联系我请加QQ好友646634621,注明添加原因

● 于 2017-12-01 09:00 ~ 2017-12-31 22:00 在魔都完成

● 文章内容来源于小麦苗的学习笔记,部分整理自网络,如有侵权或不当之处还请谅解

● 版权全部,欢迎分享本文,转载请保留出处

.............................................................................................................................................

小麦苗的微店https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

小麦苗出版的数据库类丛书http://blog.itpub.net/26736162/viewspace-2142121/

.............................................................................................................................................

使用微信客户端扫描下面的二维码来关注小麦苗的微信公众号(xiaomaimiaolhr)及QQ群(DBA宝典),学习最实用的数据库技术。

   小麦苗的微信公众号      小麦苗的DBA宝典QQ群2     《DBA笔试面宝典》读者群       小麦苗的微店

.............................................................................................................................................

ico_mailme_02.png
DBA笔试面试讲解群
《DBA宝典》读者群 欢迎与我联系




来自 “ ITPUB博客 ” ,连接:http://blog.itpub.net/26736162/viewspace-2149312/,如需转载,请注明出处,不然将追究法律责任。

相关文章
相关标签/搜索