一个删除数据的trick
Posted bisal(Chen Liu)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个删除数据的trick相关的知识,希望对你有一定的参考价值。
碰巧看到朋友圈提的一个问题,一张测试表,装载了10万的数据,
SQL> create table test(id number, c1 varchar2(30));
Table created.
SQL> select count(*) from test;
COUNT(*)
----------
100000
开启允许行迁移,删除了所有数据,同时执行了shrink space操作,想的是可以主动做空间回收,
SQL> alter table test enable row movement;
Table altered.
SQL> delete from test;
100000 rows deleted.
SQL> commit;
Commit complete.
SQL> alter table test shrink space;
Table altered.
但是检索这张表的统计信息,发现数据块、行数仍然是删除之前的状态,
SQL> exec print_table('select table_name, blocks, empty_blocks, num_rows from user_tables where table_name = ''TEST''');
TABLE_NAME : TEST
BLOCKS : 622
EMPTY_BLOCKS : 0
NUM_ROWS : 100000
-----------------
PL/SQL procedure successfully completed.
按说确实删除了数据,而且执行了shrink,应该回收了空间,但是统计信息跟我们反馈的是相反的,这是什么原因?
可能一些有经验的朋友看到这,应该能猜到问题是什么了。
Oracle的统计信息,有自动和手工两种更新方式,"自动"更新统计信息,一种是指某些操作执行完成,会触发统计信息的采集,例如创建索引,另外一种是数据库中通过window和job配合执行的一个定时任务,执行时间在不同的版本可能有所不同,例如11g,工作日从22:00开始做统计信息的更新采集。"手动"更新统计信息就是通过dbms_stats包各种gather_*存储过程,进行统计信息的采集。
如上问题中,显然是可能没到自动采集统计信息的时间点,同时没执行手工采集统计信息的操作,可以验证,如上删除了所有的数据,接着执行,
SQL> exec dbms_stats.gather_table_stats('BISAL','TEST');
PL/SQL procedure successfully completed.
此时就可以看到统计信息显示数据都是空的了,
SQL> exec print_table('select table_name, blocks, empty_blocks, num_rows from user_tables where table_name = ''TEST''');
TABLE_NAME : TEST
BLOCKS : 1
EMPTY_BLOCKS : 0
NUM_ROWS : 0
-----------------
PL/SQL procedure successfully completed.
刚才提到的某些操作会自动触发统计信息的采集,至于原因,可以参考《表和索引统计信息自动采集的问题》和《truncate表,会将统计信息清除么?》等历史文章。
实践是检验真理的唯一标准,当我们对某个现象不很确定的时候,动手操作一下,很可能就会让你印象深刻,除此之外,知其然更要知其所以然,能让你得到更多的经验。
这些都是前辈们为我们证明过的、屡试不爽的,但是真轮到我们自己,就可能因为惰性,有所裁减,建议还是要坚持,一起共勉了。
如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发pyq,
近期更新的文章:
《什么是红圈所?》
近期的热文:
文章分类和索引:
以上是关于一个删除数据的trick的主要内容,如果未能解决你的问题,请参考以下文章
2021/6/12 刷题笔记删除链表的倒数第 N 个结点与快慢指针