问:通常我们通过select count(*) from table来获取表的行数,另外user_tables数据字典视图也提供了num_rows字段来查询对象的记录数,为什么有时候二者的查询结果不一致呢?
答:是的,Oracle提供了多种方法来查询表的记录数,count和num_rows是其中常用的两种。num_rows 是对表做 statistics analysis 后填充而来,有时会有延迟,甚至为null。
我们通过两个例子看一下,首先,我们在scott用户下对salgrade表执行两次插入操作并提交;然后,我们通过create table ... as ...拷贝一张新表salgradecopy。
从测试结果来看,
salgrade表的num_rows结果和count不一致(count是正确的),salgradecopy表的
num_rows结果为null。
通常来说,Oracle会定时收集统计信息,那时num_rows和count就会达成一致。那么,有没有其他办法来让二者及时同步呢?答案是肯定的,因为我们可以手动收集统计信息。有两种方法dbms_stats.gather_table_stats与analyze table,我们可以看一下效果。
从执行结果来看,salgrade表的num_rows值由5变为20,salgradecopy表的num_rows值由null变为20。这样,两张表的count和num_rows值就达成了一致。
通常推荐使用dbms_stats来取代analyze,理由如下:
a) 可以并行进行,对多个用户,多个Table
b) 可以得到整个分区表的数据和单个分区的数据。
c) 可以在不同级别上Compute Statistics:单个分区,子分区,全表,所有分区
d) 可以倒出统计信息
e) 可以用户自动收集统计信息
当然DBMS_STATS也有缺点, 我们可以根据具体场景来选择具体使用哪种工具:
a) 不能Validate Structure
b) 不能收集CHAINED ROWS, 不能收集CLUSTER TABLE的信息,这两个仍旧需要使用Analyze语句。
c) DBMS_STATS 默认不对索引进行Analyze,因为默认Cascade是False,需要手工指定为True
答:是的,Oracle提供了多种方法来查询表的记录数,count和num_rows是其中常用的两种。num_rows 是对表做 statistics analysis 后填充而来,有时会有延迟,甚至为null。
我们通过两个例子看一下,首先,我们在scott用户下对salgrade表执行两次插入操作并提交;然后,我们通过create table ... as ...拷贝一张新表salgradecopy。
点击(此处)折叠或打开
- SQL>
- SQL> select table_name,num_rows from user_tables;
-
- TABLE_NAME NUM_ROWS
- ------------------------------ ----------
- DEPT 4
- EMP 12
- BONUS 0
- SALGRADE 5
-
- SQL>
- SQL> insert into salgrade select * from salgrade;
-
- 已创建5行。
-
- SQL> /
-
- 已创建10行。
-
- SQL> commit;
-
- 提交完成。
-
- SQL>
- SQL> select count(*) from salgrade;
-
- COUNT(*)
- ----------
- 20
-
- SQL>
- SQL> select table_name,num_rows from user_tables;
-
- TABLE_NAME NUM_ROWS
- ------------------------------ ----------
- DEPT 4
- EMP 12
- BONUS 0
- SALGRADE 5
- SQL>
- SQL> create table salgradecopy as select * from salgrade;
-
- 表已创建。
-
- SQL> select count(*) from salgradecopy;
-
- COUNT(*)
- ----------
- 20
-
- SQL> select table_name,num_rows from user_tables;
-
- TABLE_NAME NUM_ROWS
- ------------------------------ ----------
- DEPT 4
- EMP 12
- BONUS 0
- SALGRADE 5
- SALGRADECOPY
-
- SQL>
通常来说,Oracle会定时收集统计信息,那时num_rows和count就会达成一致。那么,有没有其他办法来让二者及时同步呢?答案是肯定的,因为我们可以手动收集统计信息。有两种方法dbms_stats.gather_table_stats与analyze table,我们可以看一下效果。
点击(此处)折叠或打开
- SQL>
- SQL> analyze table salgrade compute statistics;
-
- 表已分析。
-
- SQL> select table_name,num_rows from user_tables;
-
- TABLE_NAME NUM_ROWS
- ------------------------------ ----------
- DEPT 4
- EMP 12
- BONUS 0
- SALGRADE 20
- SALGRADECOPY
-
- SQL>
- SQL> exec dbms_stats.gather_table_stats('SCOTT','SALGRADECOPY');
-
- PL/SQL 过程已成功完成。
-
- SQL> select table_name,num_rows from user_tables;
-
- TABLE_NAME NUM_ROWS
- ------------------------------ ----------
- DEPT 4
- EMP 12
- BONUS 0
- SALGRADE 20
- SALGRADECOPY 20
-
- SQL>
通常推荐使用dbms_stats来取代analyze,理由如下:
- dbms_stats可以并行分析
- dbms_stats有自动分析的功能(alter table monitor )
- analyze 分析统计信息有时不准确
a) 可以并行进行,对多个用户,多个Table
b) 可以得到整个分区表的数据和单个分区的数据。
c) 可以在不同级别上Compute Statistics:单个分区,子分区,全表,所有分区
d) 可以倒出统计信息
e) 可以用户自动收集统计信息
当然DBMS_STATS也有缺点, 我们可以根据具体场景来选择具体使用哪种工具:
a) 不能Validate Structure
b) 不能收集CHAINED ROWS, 不能收集CLUSTER TABLE的信息,这两个仍旧需要使用Analyze语句。
c) DBMS_STATS 默认不对索引进行Analyze,因为默认Cascade是False,需要手工指定为True
hoegh
2016.01.05
-- The End --
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30162081/viewspace-1971706/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/30162081/viewspace-1971706/