在查看MySQL优化的过程中会看到使用临时表,这里就说明一下临时表的用法!
参考博客: https://www.cnblogs.com/duanxz/p/3724120.html
和之前一样理论的东西可能来自这个博客或者官方文档的补充,但是实例都是自己测试的。
MySQL 临时表在我们需要保存一些临时数据时是非常有用的。临时表只在当前连接可见,当关闭连接时,MySQL会自动删除表并释放所有空间。
使用其他MySQL客户端程序连接MySQL数据库服务器来创建临时表,那么只有在关闭客户端程序时才会销毁临时表,当然也可以手动删除。
You can use the TEMPORARY keyword when creating a table. A TEMPORARY table is visible only within the current session, and is dropped automatically when the session is closed. This means that two different sessions can use the same temporary table name without conflicting with each other or with an existing non-TEMPORARY table of the same name. (The existing table is hidden until the temporary table is dropped.)可以使用TEMPORARY关键字创建临时表,临时表仅对当前会话可见,当会话断开的时候临时表自动删除。这意味着两个不同的会话可以使用相同名字的临时表而没有冲突;也可以和非临时表同名,同名的非临时表会被隐藏,知道临时表删除才会出现。
临时表与数据库的关系非常松散,删除数据库不会删除数据库下面的临时表。
外部临时表的使用在之前的一篇博客提到过:https://www.cnblogs.com/wxzhe/p/9767991.html
这里只说明几点需要注意的问题:
mysql> select * from tmp_tb1, tmp_tb1 as tmptb; ERROR 1137 (HY000): Can't reopen table: 'tmp_tb1' mysql>
mysql> show create table tmp_tb1\G *************************** 1. row *************************** Table: tmp_tb1 Create Table: CREATE TEMPORARY TABLE `tmp_tb1` ( `id` int(3) DEFAULT NULL, `name` varchar(6) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql> show tables; +------------------+ | Tables_in_mytest | +------------------+ | articles | | hostinfo | | tb1 | | tb2 | | tb3 | | user_stopword | +------------------+ 6 rows in set (0.00 sec) mysql>
mysql> rename table tmp_tb1 to tmp_tb2; ERROR 1017 (HY000): Can't find file: './mytest/tmp_tb1.frm' (errno: 2 - No such file or directory)
内部临时表这里,我们先看一下官方文档的描述:在某些情况下,服务器在处理语句的过程中创建内部临时表,这种情况发生时,用户不能直接的控制。
In some cases, the server creates internal temporary tables while processing statements. Users have no direct control over when this occurs.
在下面的情况下,MySQL会使用临时表:
The server creates temporary tables under conditions such as these:【在下面这些情况下,服务器将创建临时表】 Evaluation of UNION statements。【Union联合查询】 Evaluation of some views, such those that use the TEMPTABLE algorithm, UNION, or aggregation.【处理视图,使用了临时表算法】 Evaluation of derived tables 【处理派生表】. Tables created for subquery or semi-join materialization。【子查询或半连接物化创建的表】 Evaluation of statements that contain an ORDER BY clause and a different GROUP BY clause, or for which the ORDER BY or GROUP BY contains columns from tables other than the first table in the join queue.【包含ORDER BY子句和其他GROUP BY子句的语句的计算,或者ORDER BY或GROUP BY包含来自连接队列中第一个表以外的表的列。】 Evaluation of DISTINCT combined with ORDER BY may require a temporary table.【distince结合order by可能需要临时表】 For queries that use the SQL_SMALL_RESULT modifier, MySQL uses an in-memory temporary table, unless the query also contains elements that require on-disk storage.【对于使用SQL_SMALL_RESULT 修饰符的查询,MySQL使用内存中的临时表,除非查询还包含需要磁盘存储的元素】 To evaluate INSERT ... SELECT statements that select from and insert into the same table, MySQL creates an internal temporary table to hold the rows from the SELECT, then inserts those rows into the target table. 【insert ....table select....table语句需要临时表】 Evaluation of multiple-table UPDATE statements.【多表更新】 Evaluation of GROUP_CONCAT() or COUNT(DISTINCT) expressions.
确定语句是否使用临时表,可以使用explain命令查看extra栏的输出是否为use temporary. [对于派生表和物化表不一定显示这样]
When the server creates an internal temporary table (either in memory or on disk), it increments the Created_tmp_tables status variable. If the server creates the table on disk (either initially or by converting an in-memory table) it increments the Created_tmp_disk_tables status variable.
一些查询条件会阻止服务器使用内存临时表而使用磁盘临时表:
These conditions qualify a UNION for evaluation without a temporary table:
内部临时表可以保存在内中使用memory存储引擎,也可以保存在磁盘上使用innodb或myisam存储引擎。
如果内部临时表被创建为内存中的表,但变得太大,MySQL会自动将其转换为磁盘临时表。内存中临时表的最大大小由tmp_table_size或max_heap_table_size值定义,以较小者为准。这与使用create table显式创建的内存表不同;对于此类表,只有max_heap_table_size变量确定表可以增长的大小,并且不存在到磁盘格式的转换。
internal_tmp_disk_storage_engine参数决定服务器使用磁盘临时表的存储引擎。
mysql> show variables like "internal_tmp_disk_storage_engine"; +----------------------------------+--------+ | Variable_name | Value | +----------------------------------+--------+ | internal_tmp_disk_storage_engine | InnoDB | +----------------------------------+--------+ 1 row in set (0.00 sec)
当使用磁盘临时表存储引擎为innodb时,查询生成的磁盘临时表遵循innodb的行和字段的限制,若是报Row size too large or Too many columns 的错误,可以把磁盘临时表存储引擎更改为myisam。
【待续】