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

看见微信群有位朋友问:

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$保存的记录。



如果您觉得此篇文章对您有帮助,欢迎关注微信公众号:bisal的个人杂货铺,您的支持是对我最大的鼓励!共同学习,共同进步:)


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7192724/viewspace-2146539/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/7192724/viewspace-2146539/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很高兴为您解答这个问题!根据您的要求,我为您介绍Hadoop的Hive组件并提供实验步骤和代码。请注意,这里的实验环境是CentOS 7.4。 1. 安装Hive 在安装Hive之前,需要先安装Hadoop和Java。按照以下步骤安装Hadoop和Java: - 下载JDK:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html - 安装JDK:tar -zxvf jdk-8u221-linux-x64.tar.gz - 设置环境变量: export JAVA_HOME=/usr/local/jdk1.8.0_221 export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=$JAVA_HOME/bin:$PATH - 下载Hadoop:http://hadoop.apache.org/releases.html - 安装Hadoop:tar -zxvf hadoop-2.7.7.tar.gz - 设置环境变量: export HADOOP_HOME=/usr/local/hadoop export PATH=$HADOOP_HOME/bin:$PATH - 启动Hadoop:start-all.sh 然后再按照以下步骤安装Hive: - 下载Hive:http://hive.apache.org/downloads.html - 安装Hive:tar -zxvf apache-hive-2.3.6-bin.tar.gz - 设置环境变量: export HIVE_HOME=/usr/local/hive export PATH=$HIVE_HOME/bin:$PATH - 配置Hive: cp $HIVE_HOME/conf/hive-env.sh.template $HIVE_HOME/conf/hive-env.sh vi $HIVE_HOME/conf/hive-env.sh 将以下两行添加到hive-env.sh文件中: export HADOOP_HOME=/usr/local/hadoop export HIVE_CONF_DIR=/usr/local/hive/conf cp $HIVE_HOME/conf/hive-default.xml.template $HIVE_HOME/conf/hive-site.xml vi $HIVE_HOME/conf/hive-site.xml 将以下内容添加到hive-site.xml文件中: <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost/metastore?createDatabaseIfNotExist=true</value> <description>JDBC connect string for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> <description>Driver class name for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>hive</value> <description>username to use against metastore database</description> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>hive</value> <description>password to use against metastore database</description> </property> - 创建数据库: mysql -uroot -p create database metastore; grant all privileges on metastore.* to 'hive'@'localhost' identified by 'hive'; flush privileges; exit; - 初始化Hive: $HIVE_HOME/bin/schematool -initSchema -dbType mysql 2. 启动Hive服务 启动Hive服务: hive 3. 创建数据库和数据 创建数据库: create database test; 切换到test数据库: use test; 创建数据: create table sales ( id int, product string, price double, time string ) row format delimited fields terminated by '\t'; 4. 导入数据 将数据文件放到HDFS上: hadoop fs -mkdir /input hadoop fs -put sales.txt /input 导入数据: load data inpath '/input/sales.txt' into table sales; 5. 数据查询和统计 查询所有数据: select * from sales; 查询某个时间段内的销售总额: select sum(price) from sales where time >= '2019-01-01' and time <= '2019-12-31'; 将字符串转换成日期格式: select cast(time as timestamp) from sales; 将日期格式转换成字符串: select from_unixtime(unix_timestamp(time, 'yyyy-MM-dd'), 'dd/MM/yyyy') from sales; 计算某个产品的平均价格: select avg(price) from sales where product = 'product1'; 6. 清除数据 清除数据truncate table sales; 7. 清除数据库 清除数据库: drop database test; 8. 分区实验 首先给person加入分区字段: create table person ( id int, name string, age int ) partitioned by (country string); 然后导入数据文件,并指定分区字段: load data local inpath '/home/hadoop/person.txt' into table person partition (country='China'); 查询数据: select * from person; 9. 分桶实验 首先给person加入分桶属性: create table person_bucket ( id int, name string, age int ) clustered by (id) into 4 buckets; 然后重新插入数据: insert into table person_bucket select * from person; 查询数据: select * from person_bucket; 10. 分区和分桶实验 可以同时对数据进行分区和分桶的操作。将person按照国家分成两个子,并在每个子中分桶: create table person_china ( id int, name string, age int ) partitioned by (country string) clustered by (id) into 4 buckets; create table person_us ( id int, name string, age int ) partitioned by (country string) clustered by (id) into 4 buckets; insert into table person_china partition (country='China') select * from person where country='China'; insert into table person_us partition (country='US') select * from person where country='US'; 查询数据: select * from person_china; select * from person_us; 这里提供的是Hive操作的基本流程,实际操作中可能需要根据实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值