1.创建一个表
create table test as select * from emp;
表已创建。
create index idx_test on test(empno);
索引已创建。
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
会话已更改。
SQL> select sysdate from dual;
SYSDATE
-------------------
2016-05-30 20:27:20
2.收集这个表的统计信息
conn / as sysdba
exec dbms_stats.gather_table_stats('scott','test');
查询这个表统计信息
conn scott/tiger
SQL> select blocks,empty_blocks,num_rows,avg_row_len from user_tables where table_name='TEST';
BLOCKS EMPTY_BLOCKS NUM_ROWS AVG_ROW_LEN
---------- ------------ ---------- -----------
4 0 14 38
收集索引的统计信息
SQL> analyze index index_test validate structure;
索引已分析
SQL> select lf_rows,del_lf_rows from index_stats;
LF_ROWS DEL_LF_ROWS
---------- -----------
14 0
查询ROWID信息
SQL> select rowid,empno from test;
ROWID EMPNO
------------------ ----------
AAAR9EAAEAAAACrAAA 7369
AAAR9EAAEAAAACrAAB 7499
AAAR9EAAEAAAACrAAC 7521
AAAR9EAAEAAAACrAAD 7566
AAAR9EAAEAAAACrAAE 7654
AAAR9EAAEAAAACrAAF 7698
AAAR9EAAEAAAACrAAG 7782
AAAR9EAAEAAAACrAAH 7788
AAAR9EAAEAAAACrAAI 7839
AAAR9EAAEAAAACrAAJ 7844
AAAR9EAAEAAAACrAAK 7876
ROWID EMPNO
------------------ ----------
AAAR9EAAEAAAACrAAL 7900
AAAR9EAAEAAAACrAAM 7902
AAAR9EAAEAAAACrAAN 7934
已选择14行。
3.模拟DML
delete test;
commit;
insert into test select * from emp;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
insert into test select * from test;
commit;
重复第二步,收集相关信息
查询相关信息
SQL> exec dbms_stats.gather_table_stats('SCOTT','TEST');
PL/SQL 过程已成功完成。
SQL> select blocks,empty_blocks,num_rows,avg_row_len from user_tables where table_name='TEST';
BLOCKS EMPTY_BLOCKS NUM_ROWS AVG_ROW_LEN
---------- ------------ ---------- -----------
8 0 448 38
SQL> analyze index index_test validate structure;
索引已分析
SQL> select lf_rows,del_lf_rows from index_stats;
LF_ROWS DEL_LF_ROWS
---------- -----------
448 0
4.闪回表到第一步查询的时间点
SQL> alter table test enable row movement;
表已更改。
SQL> flashback table test to timestamp to_timestamp('2016-05-30 20:27:20','yyyy-mm-dd hh24:mi:ss');
闪回完成。
先查询一个统计信息
SQL> select blocks,empty_blocks,num_rows,avg_row_len from user_tables where table_name='TEST';
BLOCKS EMPTY_BLOCKS NUM_ROWS AVG_ROW_LEN
---------- ------------ ---------- -----------
8 0 448 38
重复第二步,收集相关信息
再次查询统计信息
SQL> exec dbms_stats.gather_table_stats('SCOTT','TEST');
PL/SQL 过程已成功完成。
SQL> select blocks,empty_blocks,num_rows,avg_row_len from user_tables where table_name='TEST';
BLOCKS EMPTY_BLOCKS NUM_ROWS AVG_ROW_LEN
---------- ------------ ---------- -----------
8 0 14 38
SQL> analyze index index_test validate structure;
索引已分析
SQL> select lf_rows,del_lf_rows from index_stats;
LF_ROWS DEL_LF_ROWS
---------- -----------
462 448
SQL> select rowid,empno from test;
ROWID EMPNO
------------------ ----------
AAAR9EAAEAAAACsAAA 7369
AAAR9EAAEAAAACsAAB 7499
AAAR9EAAEAAAACsAAC 7521
AAAR9EAAEAAAACsAAD 7566
AAAR9EAAEAAAACsAAE 7654
AAAR9EAAEAAAACsAAF 7698
AAAR9EAAEAAAACsAAG 7782
AAAR9EAAEAAAACsAAH 7788
AAAR9EAAEAAAACsAAI 7839
AAAR9EAAEAAAACsAAJ 7844
AAAR9EAAEAAAACsAAK 7876
ROWID EMPNO
------------------ ----------
AAAR9EAAEAAAACsAAL 7900
AAAR9EAAEAAAACsAAM 7902
AAAR9EAAEAAAACsAAN 7934
已选择14行。
理解ROWID为什么改变
理解索引的信息为什么没变
理解统计信息在没有收集统计信息之前为什么查不到(统计信息在数据字典里,闪回,只是闪回表的数据,跟数据字典中保存的统计信息没有关联)
undo:闪回表时里面的rowid,有可能被其他事务占用,行移动时rowid就失效了,利用反sql闪回表时,DML重新构造表,闪回回去了找哪些高水位线以前未使用完的块
所以rowid有可能变有可能没变,取决于rowid有没有被其他事务占用,跟undo段的空间有关(空间比较大时就不会被占用,空间小时就有可能被占用)
索引:闪回表时,是利用的是反sql闪回DML,会利用undo数据帮我们重构索引,即闪回DML会自动恢复索引