060016002F060000 1940047 1940079 AAAV4EAABAAARfpAAN DELETE insert into "SYS"."TEST"("EMPNO","SAL") values ('7934','1300');
060016002F060000 1940047 1940079 AAAV4EAABAAARfpAAM DELETE
(篇幅原因,有省略……)
15 rows selected
Executed in 0.094 seconds
从10s到0.09s,这就是巨大的性能差异。我们可以从执行计划角度分析一下原因。
SQL> explain plan for select xid, start_scn, commit_scn, row_id, operation,undo_sql from flashback_transaction_query where xid='060016002F060000';
Explained
Executed in 0.172 seconds
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1115820779
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2063 | 0 (0)| 00:00:01 |
|* 1 | FIXED TABLE FULL| X$KTUQQRY | 1 | 2063 | 0 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(RAWTOHEX("XID")='060016002F060000')
13 rows selected
Executed in 0.67 seconds
基础表x$ktuqqry显然是保存UNDO Transaction Log中基础数据的地方,如果使用字符串类型,发现Oracle会自动进行rawtohex操作,对列函数操作如果没有函数索引的话通常是直接进行全表扫描。
从执行计划上,FIXED TABLE FULL显然也就是执行基础表全表扫描过程。
如果我们对字符串进行处理一下呢?
SQL> explain plan for select xid, start_scn, commit_scn, row_id, operation,undo_sql from flashback_transaction_query where xid=hextoraw('060016002F060000');
Explained
Executed in 0 seconds
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1747778896
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2063 | 0 (0
|* 1 | FIXED TABLE FIXED INDEX| X$KTUQQRY (ind:1) | 1 | 2063 | 0 (0
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("XID"=HEXTORAW('060016002F060000') )
13 rows selected
Executed in 0.093 seconds
执行计划中FIXED TABLE FIXED INDEX,显然是数据表固定索引路径,性能速度快也就可想而知了。对于一些事务量比较大,flashback transaction记录比较多的情况,出于性能考量需要对字符串进行处理。
4、结论
Oracle Flashback Transaction Query是我们在事务粒度级别进行逻辑恢复的手段。