MySQL 用户临时表

MySQL 用户临时表

  • 临时表的特性
  • 临时表
  • 临时表重名
  • 临时表/主备复制

优化 Join 用临时表 :

create temporary table temp_t like t1;
alter table temp_t add index(b);

insert into temp_t select * from t2 where b >= 1 and b <= 2000;

select * from t1 join temp_t on (t1.b = temp_t.b);

临时表/内存表区别 :

  • 内存表 : 用 Memory 引擎的表,建表语法是 create table … engine=memory。数据保存在内存里,系统重启时会被清空,但表结构还在
  • 临时表 : 能用 InnoDB 引擎或 MyISAM 引擎的临时表,写数据会写到磁盘上。也可用 Memory 引擎的临时表

临时表的特性

临时表的特点:

  • 建表语法: create temporary table …
  • 临时表只能被创建它的 session 访问,其他线程不可见
  • 临时表能与普通表同名
  • 有同名的临时表和普通表时,show create , 增删改查访问的是临时表
  • show tables 不显示临时表
session A session B
create temporary table t(c int) engine = myisam;
show create table t; (返回空)
create table t(id int primary key) engine = innodb;
show create table t; (临时表)
show tables; (普通表)
insert into t values(1);
select * from t; (返回 1)
select * from t; (返回空)

临时表适合 Join 优化的原因 :

  • 不同 session 的临时表能重名,当多个 session 同时执行 Join 优化时,不用担心表名重复,而导致建表失败的问题
  • 不用担心数据删除问题。当流程过程中发生异常断开,临时表能自动回收

临时表

分库分表 : 把逻辑大表分散到不同的数据库实例上

  • 如 : 将大表 ht,按字段 f,分成 1024 个分表,并分布到 32 个数据库实例上

MySQL 用户临时表_第1张图片

按分表规则 (如 : N%1024 ) 确认数据在哪个分表上 :

select v from ht where f = N;

查询没用到分区字段 f,只能到所有的分区中找,再统一做 order by :

select v from ht where k >= M 
order by t_modified desc limit 100;

实现方法 :
方法一 : proxy 层的排序

  • 优势 : 处理速度快,拿到分库数据后,直接在内存中计算
  • 缺点:要求中间层的开发能力较高;对 proxy 端的压力较大,容易出现内存不够或 CPU 瓶颈

方法二 : 把各个分库拿到的数据,汇总到一个 MySQL 实例的一个表中,再进行逻辑处理

类似执行流程 :

  1. 在汇总库上创建临时表 temp_ht,表有字段 v、k、t_modified
  2. 在各个分库上执行
select v, k, t_modified from ht_x 
where k >= M order by t_modified desc limit 100;
  1. 把分库执行的结果插入到 temp_ht 表中
  2. 执行
select v from temp_ht 
order by t_modified desc limit 100; 

MySQL 用户临时表_第2张图片

临时表重名

InnoDB 表创建 frm 文件保存表结构定义,还另存表数据

create temporary table temp_t(
  id int primary key
)engine = innodb;

frm 文件放在临时文件目录下,文件名前缀是 #sql{进程 id}{线程 id} 序列号 ,后缀是 .frm

  • select @@tmpdir : 查看实例的临时文件目录

不同 MySQL 处理不同文件 :

  • 5.6 前 :会在临时文件目录下创建一个相同前缀、以 .ibd 为后缀的文件,用来存放数据文件
  • 5.7 后 : 引入了临时文件表空间,专门存放临时文件的数据。就不用再创建 .ibd 文件

临时表的表名 :

  • 该进程的进程号是 1234
  • session A 线程 id : 4
  • session B 线程 id : 5
session A session B
create temporary table t1...; (sql4d2_4_0.frm)
create temporary table t2...; (sql4d2_4_1.frm)
create temporary table t1...; (sql4d2_5_0.frm)

临时表/主备复制

  • binlog_format=row : 与临时表相关的,不会记录到 binlog 中
  • binlog_format=statment/mixed: binlog 会记录临时表

主库执行 ( binlog_format=row ) :

drop table t_normal, temp_t

binlog 记录 : 对原来SQL 进行重写

DROP TABLE `t_normal` /* generated by server */

主库上不同的线程创建同名的临时表,备库怎么处理

主备库的临时表 :

M sessionA M sessionB S 日志
T1 create temporary table t1 …;
T2 create temporary table t1 …;
T3 create temporary table t1 …;
T4 create temporary table t1 …;

备库会把这两个 t1 表当成两个不同的临时表 :

  • session A 的临时表 t1,在备库的 table_def_key :库名 +t1 “M 的serverid” + “session A 的 thread_id”
  • session B 的临时表 t1,在备库的 table_def_key :库名 +t1+ “M 的 serverid” + “session B 的 thread_id”

你可能感兴趣的:(MySQL,mysql,数据库,sql,java,redis)