临时表

    本文介绍了 TiDB 临时表的使用场景、临时表类型、使用示例、限制临时表内存占用的方法、与其他 TiDB 功能的兼容性限制。

    TiDB 临时表主要应用于以下业务场景:

    • 缓存业务的中间临时数据,计算完成后将数据转储至普通表,临时表会自动释放。
    • 短期内对同一数据进行多次 DML 操作。例如在电商购物车应用中,添加、修改、删除商品及完成结算,并移除购物车信息。
    • 快速批量导入中间临时数据,提升导入临时数据的性能。
    • 批量更新数据。将数据批量导入到数据库的临时表,修改完成后再导出到文件。

    临时表类型

    TiDB 的临时表分为本地临时表和全局临时表:

    • 本地临时表的表定义和表内数据只对当前会话可见,适用于暂存会话内的中间数据。
    • 全局临时表的表定义对整个 TiDB 集群可见,表内数据只对当前事务可见,适用于暂存事务内的中间数据。

    本地临时表的语义与 MySQL 临时表一致,它有以下特性:

    • 本地临时表的表定义不持久化,只在创建该表的会话内可见,其他会话无法访问该本地临时表
    • 不同会话可以创建同名的本地临时表,各会话只会读写该会话内创建的本地临时表
    • 本地临时表的数据对会话内的所有事务可见
    • 在会话结束后,该会话创建的本地临时表会被自动删除
    • 本地临时表可以与普通表同名,此时在 DDL 和 DML 语句中,普通表被隐藏,直到本地临时表被删除

    用户可通过 语句创建本地临时表,通过 DROP TABLEDROP TEMPORARY TABLE 语句删除本地临时表。

    不同于 MySQL,TiDB 本地临时表都是外部表,SQL 语句不会创建内部临时表。

    假设已存在普通表 users:

    在会话 A 中创建本地临时表 users,不会有名字冲突。会话 A 访问 users 时,访问的是本地临时表 users

    1. CREATE TEMPORARY TABLE users (
    2. id BIGINT,
    3. name VARCHAR(100),
    4. city VARCHAR(50),
    5. PRIMARY KEY(id)
    6. );
    1. Query OK, 0 rows affected (0.01 sec)
    1. INSERT INTO users(id, name, city) VALUES(1001, 'Davis', 'LosAngeles');
    1. Query OK, 1 row affected (0.00 sec)
    1. SELECT * FROM users;
    1. +------+-------+------------+
    2. | id | name | city |
    3. +------+-------+------------+
    4. | 1001 | Davis | LosAngeles |
    5. 1 row in set (0.00 sec)

    在会话 B 中创建本地临时表 users,不会与普通表 users 冲突,也不会与会话 A 中的本地临时表 users 冲突。会话 B 内访问 users 时,访问的是会话 B 内创建的本地临时表 users 数据。

    1. CREATE TEMPORARY TABLE users (
    2. id BIGINT,
    3. name VARCHAR(100),
    4. PRIMARY KEY(id)
    5. );
    1. Query OK, 0 rows affected (0.01 sec)

    此时将数据插入 users,插入到的是会话 B 中的本地临时表 users

    1. Query OK, 1 row affected (0.00 sec)
    1. SELECT * FROM users;
    1. +------+-------+---------+
    2. | id | name | city |
    3. +------+-------+---------+
    4. | 1001 | James | NewYork |
    5. +------+-------+---------+
    6. 1 row in set (0.00 sec)

    TiDB 本地临时表的以下特性与限制与 MySQL 一致:

    • 创建、删除本地临时表时,不会自动提交当前事务
    • 删除本地临时表所在的 schema 后,临时表不会被删除,仍然可以读写
    • 创建本地临时表需要 CREATE TEMPORARY TABLES 权限,随后对该表的所有操作不需要权限
    • 本地临时表不支持外键和分区表
    • 不支持基于本地临时表创建视图
    • SHOW [FULL] TABLES 不显示本地临时表

    TiDB 本地临时表与 MySQL 临时表有以下方面不兼容:

    • TiDB 本地临时表不支持 ALTER TABLE
    • TiDB 本地临时表忽略 ENGINE 表选项,始终在 TiDB 内存中暂存临时表数据,并且有
    • 当声明存储引擎为 MEMORY 时,TiDB 本地临时表没有 MEMORY 存储引擎的限制
    • 当声明存储引擎为 INNODBMYISAM 时,TiDB 本地临时表忽略 InnoDB 临时表特有的系统变量
    • MySQL 不允许在同一条 SQL 中多次引用同一张临时表,而 TiDB 本地临时表没有该限制
    • MySQL 中用于显示临时表的 information_schema.INNODB_TEMP_TABLE_INFO 表在 TiDB 中不存在。TiDB 暂无用于显示本地临时表的系统表。
    • TiDB 没有内部临时表,MySQL 针对内部临时表的系统变量对 TiDB 不生效

    全局临时表

    全局临时表是 TiDB 的扩展功能,它有以下特性:

    • 全局临时表的表定义会持久化,对所有会话可见
    • 全局临时表的数据只对当前的事务内可见,事务结束后数据自动清空
    • 全局临时表不能与普通表同名

    用户可通过 CREATE GLOBAL TEMPORARY TABLE 语句创建全局临时表,语句末尾要加上 ON COMMIT DELETE ROWS。可通过 DROP TABLEDROP GLOBAL TEMPORARY TABLE 语句删除全局临时表。

    在会话 A 中创建全局临时表 users

    1. CREATE GLOBAL TEMPORARY TABLE users (
    2. id BIGINT,
    3. name VARCHAR(100),
    4. city VARCHAR(50),
    1. Query OK, 0 rows affected (0.01 sec)

    写入 users 的数据对当前事务可见:

    1. BEGIN;
    1. Query OK, 0 rows affected (0.00 sec)
    1. INSERT INTO users(id, name, city) VALUES(1001, 'Davis', 'LosAngeles');
    1. SELECT * FROM users;
    1. +------+-------+------------+
    2. | id | name | city |
    3. +------+-------+------------+
    4. | 1001 | Davis | LosAngeles |
    5. +------+-------+------------+
    6. 1 row in set (0.00 sec)
    1. COMMIT;
    1. Query OK, 0 rows affected (0.00 sec)
    1. SELECT * FROM users;
    1. Empty set (0.00 sec)

    会话 A 创建了 users 后,会话 B 也可以读写该表:

    1. SELECT * FROM users;
    1. Empty set (0.00 sec)

    无论定义表时声明的 ENGINE 是哪种存储引擎,本地临时表和全局临时表的数据都只暂存在 TiDB 实例的内存中,不持久化。

    为了避免内存溢出,用户可通过系统变量 限制每张临时表的大小。当临时表大小超过限制后 TiDB 会报错。tidb_tmp_table_max_size 的默认值是 64MB

    例如,将每张临时表的大小限制为 256MB

    与其他 TiDB 功能的兼容性限制

    以下是本地临时表和全局临时表都不支持的功能:

    • 不支持 AUTO_RANDOM
    • 不支持 SHARD_ROW_ID_BITSPRE_SPLIT_REGIONS 表选项
    • 不支持分区表
    • 不支持 SPLIT REGION 语句
    • 不支持 ADMIN CHECK TABLEADMIN CHECKSUM TABLE 语句
    • 不支持 FLASHBACK TABLERECOVER TABLE 语句
    • 不支持以临时表为源表执行 语句
    • 不支持 Stale Read
    • 不支持外键
    • 不支持 SQL binding
    • 不支持添加 TiFlash 副本
    • 不支持在临时表上创建视图
    • 不支持 Placement Rules
    • 包含临时表的执行计划不会被 prepared plan cache 缓存

    以下是只有本地临时表不支持的功能:

    • 不支持通过系统变量 tidb_snapshot 读取历史数据

    本地临时表只对当前会话可见,因此本地临时表不会被 TiDB 数据迁移工具导出、备份、同步。

    另请参阅