Oracle对表、索引和簇的分析
分析Oracle的表、索引或簇,可以采集其有关的数据,或者校验其存储格式的合法性。还可以分析这些模式对象以便收集或更新指定对象的统计数据。当发布DDL语句时,参照对象的统计数据被用于确定该语句的最有效的执行方案。即使用CBO就需要有足够的分析数据。
一、使用表、索引、簇的统计表
使用ANALYZE语句来收集统计信息到数据字典中。当使用CBO来执行SQL时,就会利用这些统计数据以得出结论。
COMPUTER STATISTICS
当计算统计数字时,扫描整个对象,收集关于此对象的数据。Oracle用这些数据来计算此对象的精确统计数据。在这些计算出的统计数据中,整个对象的微小变化都被计算出来。因为为了收集计算统计数据的信息要扫描整个对象,所以对象的体积越大,收集所有信息所要做的工作就越多。
ESTIMATE STATISTICS
当估计统计数据时,Oracle收集对象的各部分有代表性的信息。该信息的子集提供了有关该对象合理的、估计的统计数据。估计出的统计出具的精确度取决于Oracle所使用的样例的代表性。因为收集估计统计数据只是扫描对象的几个部分,因此能快速得分析一个对象,也可以随意得指定Oracle在做估计时所使用的行的数量和百分比。
注意:在计算表或簇的统计数据时,需要有足够的临时空间。但分析索引时不需要临时空间。
二、使用ANALYZE语句计算统计数据
ANALYZE TABLE emp COMPUTE STATISTICS; --完全统计
ANALYZE TABLE emp ESTIMATE STATISTICS; --默认的1064行统计样例
ANALYZE TABLE emp ESTIMATE STATISTICS SAMPLE 2000 ROWS; --用2000行做统计样例
ANALYZE TABLE emp ESTIMATE STATISTICS SAMPLE 33 PERCENT; --用33%做统计样例
统计得到的信息有以下这些(带*号的表示数据是精确的)
表:
● 行数
● 已经使用的数据块数*
● 从未使用的数据块数
● 平均可用的空闲空间
● 链接行的数目
● 平均行长度
● 列中不同的值的数目
● 列的下限值*
● 列的上限值*
索引:
● 索引层次*
● 叶子数据块的数目
● 不同的键的数目
● 每个键的叶子数据块的平均数目
● 每个键的数据块的平均数目
● 分簇因子
注意:若一个索引已标记为UNUSABLE,则在分析时报错,必须删除或重建后才能分析。
簇:
● 簇键链的平均长度
注:当分析簇的统计数据时,簇中的表盒索引的统计信息会被自动收集
三、操作对象的统计数据
1、查看统计信息
DBA|ALL|USER_INDEXES
DBA|ALL|USER_TABLES
DBA|ALL|USER_TAB_COLUMNS
注意:这些表中的上面所列统计信息,如果不ANALYZE的话,是一直不变的。
2、删除统计信息
ANALYZE TABLE emp DELETE STATISTICS;
删除后可以防止table再使用CBO
3、其他的统计方法
使用PLSQL包也可以对表进行数据统计分析
DBMS_STATS:这个当然是最强大的分析包了
DBMS_UTILITY.ANALYZE_SCHEMA:可直接分析SCHEMA中所有对象
DBMS_DDL.ANALYZE_OBJECT:收集对象的的统计信息
四、校验表、索引、簇和物化视图
为了校验表、索引、簇和物化视图的结构的完整性,使用带有VALIDATE STRUCTURE选项的ANALYZE语句,如果返回错误消息,则说明该对象已损坏。如果对象损坏,则需要删除并重建。如果是物化视图,则仅需要重新完全刷新一遍
校验的语句如下:
ANALYZE TABLE emp VALIDATE STRUCTURE;
如果需要校验与某对象有关联的所有对象是否有效,则使用CASCADE子句:
ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE;
再加入联机结构校验:
ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE ONLINE;
五、列出表和簇的链接行
可使用LIST CHAINED ROWS选项的ANALYZE语句,查看表或簇中链接的或迁移的行。这条语句的执行结果存储在制定的表中,该表被明确得创建,以便直接接收由LIST CHAINED ROWS子句返回的值。
1、创建CHAINED_ROWS表
创建用于接收由ANALYZE LIST CHAINED ROWS语句返回的数据的表,执行'D:\oracle\ora92\rdbms\admin\utlchain.sql'(这个脚本其实就是一个简单的table创建语句)。
创建之后,使用ANALYZE语句的语法如下:
ANALYZE CLUSTER emp_dept CHAINED ROWS INTO CHAINED_ROWS;
2、删除表中的迁移或链接行
使用CHAINED_ROWS表中的信息,可减少或删除现存表中的迁移或链接行,步骤如下:
①使用ANALYZE语句收集迁移或链接行信息
ANALYZE TABLE order_hist LIST CHAINED ROWS;
②查询输出表
SELECT * FROM CHAINED_ROWS
WHERE TABLE_NAME = 'ORDER_HIST';
在输出结果中会显示迁移或者链接的所有行
③如果输出表显示出有许多迁移或链接行,则开始执行删除迁移行:
④创建一个与现存表相同列的中间表,以便保留迁移或链接行
CREATE TABLE int_order_hist
AS SELECT * FROM order_hist
WHERE ROWID IN
(SELECT HEAR_ROWID
FROM CHAINED_ROWS
WHERE TABLE_NAME = 'ORDER_HIST');
⑤从现存的表中删除迁移或链接行
DELETE FROM order_hist
WHERE ROWID IN
(SELECT HEAR_ROWID
FROM CHAINED_ROWS
WHERE TABLE_NAME = 'ORDER_HIST');
⑥把中间表中的行插入到现存表中
INSERT INTO order_hist
SELECT * FROM int_order_hist;
⑦删除中间表
DROP TABLE int_order_hist;
⑧从输出表中删除步骤1所收集的信息
DELETE FROM CHAINED_ROWS
WHERE TABLE_NAME = 'ORDER_HIST';
⑨再次使用ANALYZE语句,查询输出表
⑩再次输出表中的所有行都是链接行,通过增加数据块大小就能消除链接行。但是很多情况下,链接问题不可避免。