技术分享 | 浅谈 MySQL 的临时表和临时文件

Posted 爱可生云数据库

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了技术分享 | 浅谈 MySQL 的临时表和临时文件相关的知识,希望对你有一定的参考价值。

作者:姚嵩

爱可生南区交付服务部经理,爱好音乐,动漫,电影,游戏,人文,美食,旅游,还有其他。虽然都很菜,但毕竟是爱好。

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


本文内容来源于对客户的三个问题的思考:

  1. 哪些 SQL 会产生临时表/临时文件
  2. 如何查看已有的临时表
  3. 如何控制临时表/临时文件的总大小

说明:

以下测试都是在 mysql 8.0.21 版本中完成,不同版本可能存在差异,可自行测试;

首先,让我们了解下什么是临时表|临时文件?

临时表和临时文件都是用于临时存放数据集的地方;

一般情况下,需要临时存放在临时表或临时文件中的数据集应该符合以下特点:

  • 数据集较小(较大的临时数据集一般意味着 SQL 较烂,当然有例外项)
  • 用完就清理(因为是临时存储数据集的地方,所以生命周期和 SQL 或者会话生命周期相同)
  • 会话隔离(因为是临时数据集,不涉及到与其他会话交互)
  • 不产生 GTID

从临时表|临时文件产生的主观性来看,分为2类:

  • 用户创建的临时表
  • SQL 产生的临时表|临时文件

用户创建临时表:

  用户创建临时表(只有创建临时表的会话才能查看其创建的临时表的内容)

create database if not exists db_test ;
use db_test ;
CREATE TEMPORARY TABLE t1 (c1 INT PRIMARY KEY) ENGINE=INNODB;
select * from db_test.t1 ;

  注意:

  可以创建和普通表同名临时表,其他会话可以看到普通表(因为看不到其他会话创建的临时表);

  创建临时表的会话会优先看到临时表;

  同名表的创建的语句如下

CREATE TABLE t1 (c1 INT PRIMARY KEY) ENGINE=INNODB;
insert into  t1 values(1);

  当存在同名的临时表时,会话都是优先处理临时表(而不是普通表),包括:select、update、delete、drop、alter 等操作;

查看用户创建的临时表:

  任何 session 都可以执行下面的语句;

  查看用户创建的当前 active 的临时表(不提供 optimizer 使用的内部 InnoDB 临时表信息)

SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO\\G

  注意

  用户创建的临时表,表名为t1,

  但是通过 INNODB_TEMP_TABLE_INFO 查看到的临时表的 NAME 是#sql开头的名字,例如:#sql45aa_7c69_2 ;

  另外 information_schema.tables 表中是不会记录临时表的信息的。

用户创建的临时表的回收:

  1. 会话断开,自动回收用户创建的临时表;
  2. 可以通过 drop table 删除用户创建的临时表,例如:drop table t1;

用户创建的临时表的其他信息&参数:

  会话临时表空间存储 用户创建的临时表和优化器 optimizer 创建的内部临时表(当磁盘内部临时表的存储引擎为 InnoDB 时);

  innodb_temp_tablespaces_dir 变量定义了创建 会话临时表空间的位置,默认是数据目录下的#innodb_temp 目录;

  文件类似temp_[1-20].ibt ;

  查看会话临时表空间的元数据:

select * from information_schema.innodb_session_temp_tablespaces ;

  用户创建的临时表删除后,其占用的空间会被释放(temp_[1-20].ibt文件会变小)。

  在 MySQL 8.0.16 之前,internal_tmp_disk_storage_engine 变量定义了用户创建的临时表和 optimizer 创建的内部临时表的引擎,可选 INNODB 和 MYISAM ;

  从 MySQL 8.0.16 开始,internal_tmp_disk_storage_engine参数被移除,默认使用InnoDB存储引擎;

  innodb_temp_data_file_path 定义了用户创建的临时表使用的回滚段的存储文件的相对路径、名字、大小和属性,该文件是全局临时表空间(ibtmp1);

  可以使用语句查询全局临时表空间的数据文件大小:

SELECT FILE_NAME, TABLESPACE_NAME, ENGINE, INITIAL_SIZE, TOTAL_EXTENTS*EXTENT_SIZE

AS TotalSizeBytes, DATA_FREE, MAXIMUM_SIZE FROM INFORMATION_SCHEMA.FILES
WHERE TABLESPACE_NAME = \'innodb_temporary\'\\G 

SQL 什么时候产生临时表|临时文件呢?

  需要用到临时表或临时文件的时候,optimizer 自然会创建使用(感觉是废话,但是又觉得有道理=.=!);

  (想象能力强的,可以牢记上面这句话;想象能力弱的,只能死记下面的 SQL 了。我也弱,此处有个疲惫的微笑

以上是关于技术分享 | 浅谈 MySQL 的临时表和临时文件的主要内容,如果未能解决你的问题,请参考以下文章

MySQL内存表和临时表

MySQL中堆表和临时表的区别?

mysql之临时表

MySQL创建临时表?

mysql存储过程中使用临时表和游标

Mysql 临时表 视图