前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >truncate表,会将统计信息清除么?

truncate表,会将统计信息清除么?

作者头像
bisal
发布2019-01-29 16:34:36
1.2K0
发布2019-01-29 16:34:36
举报

看见微信群有位朋友问:

truncate表,会将统计信息清除么?

有些朋友回复,

数据字典信息都没有了,统计信息就清除了,所以是没有统计信息的。 做个实验,跟踪一下truncate,应该比较清楚。 我做了10g的测试,发现那个表的last_analyzed还是有记录的。 truncate完统计信息还是在的,跟你10g还是11g没有关系,关键在你之前有没有收集统计信息,你之前都没有收集统计信息,last analyzed本来就是空的。 之前有记录,last_analyzed是不为空的,truncate表后,这个变成了空。

第二位朋友说的很对,究竟会不会删除统计信息,做一下实验,就可以了解了。

创建测试表,

SQL> create table test (id number, name varchar2(1)); Table created. SQL> begin ?????? for i in 1 .. 10000 loop ???????? insert into test values(i, dbms_random.string('a',1)); ?????? end loop; ?????? commit; ???? end; ???? / PL/SQL procedure successfully completed. SQL> create index idx_test on test(id); Index created. SQL> select count(*) from test; ? COUNT(*) ---------- ???? 10000

此时检索表的统计信息,记录是空的,检索索引的统计信息,是有记录的,

SQL> select num_rows, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_tables where table_name='TEST'; ? NUM_ROWS LAST_ANALYZED ? --------------- ----------------------------------------- SQL> select num_rows, sample_size, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_indexes where table_name='TEST'; ? NUM_ROWS SAMPLE_SIZE LAST_ANALYZED ---------- ----------- ----------------------------- ???? 10000?? ?????? 10000 2017-10-08 15:55:42

手工以cascade=false收集统计信息,

SQL> exec dbms_stats.gather_table_stats('BISAL','TEST',cascade=>false); PL/SQL procedure successfully completed.

可以看出,表的统计信息已近更新了,

SQL> select num_rows, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_tables where table_name='TEST'; ? NUM_ROWS LAST_ANALYZED ---------- -------------------- ???? 10000 2017-10-08 16:04:16

但是由于cascade=false,因此不会自动采集索引,

SQL> select num_rows, sample_size, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_indexes where table_name='TEST'; ? NUM_ROWS SAMPLE_SIZE LAST_ANALYZED ---------- ----------- ----------------------------- ???? 10000?? ?????? 10000 2017-10-08 15:55:42

以cascade=true采集统计信息,表和索引的统计信息更新了,

SQL> exec dbms_stats.gather_table_stats('BISAL','TEST',cascade=>true); PL/SQL procedure successfully completed. SQL> select num_rows, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_tables where table_name='TEST'; ? NUM_ROWS LAST_ANALYZED ---------- -------------------- ???? 10000 2017-10-08 16:07:18 SQL> select num_rows, sample_size, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_indexes where table_name='TEST'; ? NUM_ROWS SAMPLE_SIZE LAST_ANALYZED ---------- ----------- --------------- ???? 10000?? ?????? 10000 2017-10-08 16:07:18

此时执行truncate,清空表数据,

SQL> truncate table test; Table truncated. SQL> select count(*) from test; ? COUNT(*) ---------- ?? ? 0

可以看出表和索引统计信息,没有被删除,

SQL> select num_rows, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_tables where table_name='TEST'; ? NUM_ROWS LAST_ANALYZED ---------- -------------------- ???? 10000 2017-10-08 16:07:18 SQL> select num_rows, sample_size, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_indexes where table_name='TEST'; ? NUM_ROWS SAMPLE_SIZE LAST_ANALYZED ---------- ----------- --------------- ???? 10000?? ?????? 10000 2017-10-08 16:07:18

执行一次统计信息采集,此时表和索引的统计信息,已经是最新了,

SQL> exec dbms_stats.gather_table_stats('BISAL','TEST',cascade=>true); PL/SQL procedure successfully completed. SQL> select num_rows, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_tables where table_name='TEST'; NUM_ROWS? LAST_ANALYZED --------- -------------------- ?????? 0? 2017-10-08 16:25:06 SQL> select num_rows, sample_size, to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from user_indexes where table_name='TEST'; ? NUM_ROWS SAMPLE_SIZE LAST_ANALYZED ---------- ----------- -------------------- ?? ??????? 0?? ?????????? 0 2017-10-08 16:25:06

说明执行truncate,表的统计信息不会被删除,除非执行了统计信息采集,truncate table和表和索引的统计信息,没有任何关联。

另一方面,truncate会影响表是否可以被自动采集统计信息的任务触发,mon_mods_all$会记录自上次自动统计信息收集作业完成之后,对所有目标表的insert、delete和update操作所影响的记录数,即DML操作次数,以及目标表是否执行过truncate操作,主要用于每日统计信息采集作业判断是否需要采集此张表,对于这张视图mon_mods_all$的介绍,可以参考eygle的文章,

http://www.eygle.com/archives/2009/09/mon_mods_is_use.html

比如如下表,记录数为10000,mon_mods_all$记录了一条信息,其中插入insert是10000,其他的字段,为空,

SQL> select count(*) from test; ? COUNT(*) ---------- ???? 10000 SQL> exec dbms_stats.flush_database_monitoring_info(); PL/SQL procedure successfully completed. SQL> select obj#, inserts, updates, deletes, flags from sys.mon_mods_all$ where obj#=18021; ? OBJ#?? INSERTS?? ?? UPDATES?? DELETES?? FLAGS ------ --------- --------- ---------- ------- ?18021?? ?? 10000?? ???????? 0?? ?????? 0?????? 0

此时执行truncate,mon_mods_all$记录未变,

SQL> truncate table test; Table truncated. SQL> select obj#, inserts, updates, deletes, flags from sys.mon_mods_all$ where obj#=18021; ?? OBJ#?? INSERTS?? ???? UPDATES?? DELETES??? FLAGS ------- ---------- ---------- --------- -------- ? 18021?? ???? 10000?? ??????? 0?? ???????? 0??????? 0

此时执行一次dbms_stats.flush_database_monitoring_info(),显示FLAGS是1,表示执行过了truncate table,

SQL> exec dbms_stats.flush_database_monitoring_info(); PL/SQL procedure successfully completed. SQL> select obj#, inserts, updates, deletes, flags from sys.mon_mods_all$ where obj#=18021; ?? OBJ#?? INSERTS?? ???? UPDATES?? DELETES??? FLAGS ------- ---------- ---------- --------- -------- ? 18021?? ???? 10000?? ??????? 0?? ????? 10000??????? 1

再次执行统计信息采集,此时mon_mods_all$的记录就会被清空,

SQL> exec dbms_stats.gather_table_stats('BISAL','TEST',cascade=>true); PL/SQL procedure successfully completed. SQL> select obj#, inserts, updates, deletes, flags from sys.mon_mods_all$ where obj#=18021; no rows selected

总结:

1. 执行truncate,表的统计信息不会被删除,除非执行了统计信息采集,truncate table和表和索引的统计信息,没有任何关联,对象是否有统计信息记录,取决于是否采集过统计信息,包括手工和自动两种方法。

2. 执行truncate,会将mon_mods_all$视图的FLAGS字段置位,变为1,自动采集统计信息作业,可以据此判断,是否需要采集这张表,当重新采集统计信息,就会删除mon_mods_all$保存的记录。

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年10月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com