本文解释 OceanBase 数据库中临时表的清理为什么会很慢的原因。
- 临时表是会话级别的。
- 当会话结束时,或者定义为 ON COMMIT DELETE ROWS 的临时表在执行 COMMIT 时,会对临时表进行数据清理操作。
- 数据清理默认一次最多删除 1000 行临时表的数据,使用循环删除的方式直至临时表中所有数据被清空。如果临时表中的数据量很大,则清理临时表的耗时会比较久。
示例如下。
创建临时表,并插入 130001 条记录,然后执行 COMMIT 操作。COMMIT 时触发了临时表的清空,COMMIT 耗时 7.4 秒。
CREATE GLOBAL TEMPORARY TABLE "TEMP_TB" ( "C1" NUMBER ) COMPRESS FOR ARCHIVE REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 ON COMMIT DELETE ROWS;obclient [TEST2]> show variables like 'autocommit'; +---------------+-------+ | VARIABLE_NAME | VALUE | +---------------+-------+ | autocommit | OFF | +---------------+-------+ 1 row in set (0.001 sec)obclient [TEST2]> insert into temp_tb select level from dual connect by level<=130001; Query OK, 130001 rows affected (3.294 sec) Records: 130001 Duplicates: 0 Warnings: 0obclient [TEST2]> commit; Query OK, 0 rows affected (7.442 sec)查看
observer.log,可以看到对临时表的清理操作时以 1000 条记录为批次进行,共删除了 130001 条记录,耗时 7.3 秒。[2023-12-18 17:01:50.206087] INFO [SQL.SESSION] ob_sql_session_info.cpp:759 [124332][0][YB420BA6506F-00060C4AE8831186-0-0] [lt=10] [dc=0] delete rows in oracle temporary table(sql=DELETE FROM "TEST2"."TEMP_TB" WHERE SYS_SESSION_ID = 286718836402462 AND ROWNUM <= 1000, affect_rows=130001, clean_time=7293019)
建议:如果数据量比较大,建议换成实体表,通过 truncate 来进行数据清理。
适用版本
OceanBase 数据库 V4.3 之前的版本。