1.临时表的特点
1.建表语法是 create temporary table…修改表名语法是alter table … rename to…
2.只对创建它的session可见,其他线程不能访问。当这个session结束会被自动删除。
3.临时表可以跟普通表同名。
4.session内有同名的普通表和临时表时,show create以及增删改查语句访问的是临时表。
5.show tables不显示临时表
2.临时表的应用
可以用于复杂查询的优化。其中,分库分表的跨库查询就是一个典型应用场景。
举例:
select v from ht where k >= M order by t_modified desc limit 100;
在实践中,我们往往会发现每个分库的计算量都不饱和,所以会直接把临时表 temp_ht 放到 32 个分库中的某一个上。
3.为什么临时表可以重名
MySQL 维护数据表,除了物理上要有文件外,内存里面也有一套机制区别不同的表,每个表都对应一个 table_def_key。
对于临时表,table_def_key 在“库名 + 表名”基础上,又加入了“server_id+thread_id”。
也就是说,session A 和 sessionB 创建的两个临时表 t1,它们的 table_def_key 不同,磁盘文件名也不同,因此可以并存。
4.临时表和主备复制
4.1
如果当前的 binlog_format=row,那么跟临时表有关的语句,就不会记录到 binlog 里。也就是说,只在 binlog_format=statment/mixed 的时候,binlog 中才会记录临时表的操作。
这种情况下,创建临时表的语句会传到备库执行,因此备库的同步线程就会创建这个临时表。主库在线程退出的时候,会自动删除临时表,但是备库同步线程是持续在运行的。所以,这时候我们就需要在主库上再写一个 DROP TEMPORARY TABLE 传给备库执行。
MySQL 在记录 binlog 的时候,不论是 create table 还是 alter table 语句,都是原样记录,甚至于连空格都不变。但是如果执行 drop table t_normal,系统记录 binlog 就会写成:
DROP TABLE ’t_normal‘ /* generated by server /
因为备库上并没有表 temp_t,将这个命令重写后再传到备库执行,才不会导致备库同步线程停止。所以,drop table 命令记录 binlog 的时候,就必须对语句做改写。“/ generated by server */”说明了这是一个被服务端改写过的命令。
4.2
主库上不同的线程创建同名的临时表是没关系的,但是传到备库执行是怎么处理的呢?