① 搜集和刪除索引、表和簇的統計信息
② 驗證表、索引和簇的結構
③ 鑒定表和簇和行遷移和行鏈接
針對analyze的搜集和刪除統計信息功能而言
Oracle推薦使用DBMS_STATS包來代替analyze搜集優化信息
DBMS_STATS可以並行的搜集信息,可以搜集分區表的全局信息
進一步來說,CBO只會使用DBMS_STATS包所統計出來的信息 https://blog.csdn.net/iteye_14608/article/details/82447870
analyze table table_name compute statistics;
2、收集表的統計信息,並且以計算模式
analyze table table_name compute statistics for table;
3、以計算模式收集索引的統計信息
analyze index index_name compute statistics;
4、以計算模式對表的列收集統計信息
analyze table table_name compute statistics for table for columns col1,col2;
4、刪除表、表的所有列及表的所有索引的統計信息
analyze table table_name delete statistics;
不要用analyze的compute 和estimate收集優化統計信息,analyze命令已經過時,一般用dbms_stats 來收集優化統計信息,dbms_stats命令可以使用parallel,對分區對象收集全局統計信息, fine tune your statistics collection in other ways. 基於成本的優化器取決於統計信息
analyze命令收集的統計信息和基於成本優化器所需統計信息無關,下列情況用analyze比dbms_stats要好:
2、 什么情況下用analyze命令
(1) 收集或者刪除索引,分區索引,表,分區表,cluster的統計信息,
analyze收集表的統計信息都放在 all_tables dba_tables user_tables 表里面了,表里的統計信息是指 NUM_ROWS、BLOCKS 、EMPTY_BLOCKS 、AVG_SPACE、CHAIN_COUNT、AVG_ROW_LEN
analyze table有如下限制: 你不能收集數據字典的統計信息
你不能收集 external table的統計信息,但是可以用dbms_stats收集
analyze 不能收集臨時表的默認統計信息
你不能compute or estimate , REF column types, varrays, nested tables, LOB column types 類型的統計信息
analyze 收集索引里的統計信息 都放在 USER_INDEXES 、dba_indexes 、ALL_INDEXES表里,表里的統計信息指BLEVEL、LEAF_BLOCKS、DISTINCT_KEYS、AVG_LEAF_BLOCKS_PER_KEY、AVG_DATA_BLOCKS_PER_KEY、CLUSTERING_FACTOR
cluster 的統計信息都放在 ALL_CLUSTERS,USER_CLUSTERS, andDBA_CLUSTERS
(2)驗證索引,分區索引,表,分區表 索引組織表 對象的結構
(3)確定表和cluster 的行連接或者遷移
3什么情況下用dbms_stats命令
一般用dbms_stats 來收集優化統計信息,dbms_stats命令可以使用parallel,對分區對象收集全局統計信息, fine tune your statistics collection in other ways. 基於成本的優化器取決於統計信息
GATHER_INDEX_STATS
GATHER_TABLE_STATS
GATHER_SCHEMA_STATS
GATHER_DATABASE_STATS
4 analyze語法
ANALYZE
{ { TABLE [ schema. ] table
| INDEX [ schema. ] index
} [ partition_extension_clause ]
| CLUSTER [ schema. ] cluster
}
{ validation_clauses
| LIST CHAINED ROWS [ into_clause ]
| DELETE [ SYSTEM ] STATISTICS
} ;
當我們收集統計信息時,如果表或索引上有大量的數據被刪除,那么如果采用compute或者 estimage 來收集,可以會進行full table scan,因此會使用很多的時間
為了驗證表,索引,cluster 物化視圖的結構完整性,可以 用analyze語句加上validate structure 選項來驗證,如果是有效的則不返回錯誤,如果結構有問題,就是返回錯誤
指定 VALIDATE REF UPDATE 去驗證指定表的ref值,檢測每個ref的rowid和它正在的rowid進行比較,如果有必要修改,就會修改,這個語句只能在分析表的時候用
如果一個表的用戶對依賴對象沒有select權限,那么oracle會認為他們是不合法的,並且設置成null,隨后在查詢時ref值也不可用,即使對此對象有合適的權限。
ANALYZE TABLE emp VALIDATE STRUCTURE;
VALIDATE STRUCTURE 用來驗證分析對象結構的合法性,此統計信息的收集不是給優化器使用
對於表,數據庫驗證了數據塊和行的完整性,對於索引組織表,數據庫也會生成主鍵的壓縮統計信息
對於cluster,數據庫自動驗證cluster table 結構的合理性
對於分區表,數據庫也會驗證每一行屬於正確的分區,如果某行分到不正確的分區,她的rowid就會插入到INVALID_ROWS表中;
對於臨時表,數據庫會在當前session中檢測表和索引的合法性
對於索引,數據庫會驗證每個索引block 的完整性和block 是否損壞。 這個命令不會確實每個表的row 是否和索引的row 匹配。你可以使用cascade來驗證
oracle為每個普通索引計算壓縮統計信息,並且存儲索引的統計信息到INDEX_STATS andINDEX_HISTOGRAM
ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE;
CASCADE 用來驗證表或者cluster以及表或cluster上的相關索引信息的合法性 ,一般cascade會進行一個完整的驗證合法性,需要消耗更多的資源
ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE FAST;
FAST 用來檢測表上存在的損壞,而不用報告具體損壞的細節,你可以用fast選項確定是否損壞,用cascade不帶fast來確定損壞的細節,如果你用此方法驗證已經enable的函數索引,那么可能會返回錯誤,你必須重建索引
ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE ONLINE;
ONLINE選項用來在DML操作正在某個對象時,驗證某個對象的合法性,為保證並發性,而降低了驗證對象的合法性的性能,當你使用online驗證對象的合法性時,不會收集對象的統計信息,當你使用offline的時候回收集統計信息。 你不能使用online分析cluster
OFFLINE :是默認值。當你使用offline的時候,會增加驗證對象合法性的性能,但是會阻礙INSERT,UPDATE, and DELETE語句訪問對象的並發性,不影響select語句,
INTO 語句僅對分區表有效,數據庫會把分區表中不合法行的rowid放到一個表中去,如果你忽略用戶模式,會認為指定的表是在當前用戶下,如果你忽略用戶模式和表,那么會認為是表名為 INVALID_ROWS ,此表的sql腳本是 $ORACLE_HOME/rdbms/admin/utlvalid.sql
create table INVALID_ROWS (
owner_name varchar2(30),
table_name varchar2(30),
partition_name varchar2(30),
subpartition_name varchar2(30),
head_rowid rowid,
analyze_timestamp date
);
ANALYZE CLUSTER emp_dept LIST CHAINED ROWS INTO CHAINED_ROWS;
LIST CHAINED ROWS 可以讓你通過分析表和cluster 確定遷移和行連接的行,你不能把這個語句用在分析索引
INTO 語句會把行連接和行遷移的行放到表中,如果你忽略用戶模式,會認為指定的表是在當前用戶下,如果你忽略用戶模式和表,那么會認為是表名為 CHAINED_ROWS,此表必須在你本地的數據庫中,創建表的腳本是
ANALYZE TABLE orders DELETE STATISTICS;
DELETE STATISTICS: 能夠刪除通過分析保存在數據字典里的信息
當你用這個語句可以自動刪除定義在表上的索引的統計信息
如果你只想刪除系統的統計信息而不刪除用戶定義的統計信息,可以指定system用戶來刪除,如果你忽略了system,那么用戶定義在的列或者索引的統計信息也會刪除
5 、 example
SQL> create table t1 as select *From emp;
表已創建
SQL> select OWNER,TABLE_NAME,STATUS,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,CHAIN_CNT,AVG_ROW_LEN from dba_tables where table_name='T1';
OWNER TABLE STATUS NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ----- -------- ---------- ---------- ------------ ---------- ---------- -----------
SCOTT T1 VALID
SQL> ANALYZE TABLE T1 COMPUTE STATISTICS;
表已分析。
SQL> select OWNER,TABLE_NAME,STATUS,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,CHAIN_CNT,AVG_ROW_LEN from dba_tables where table_name='T1';
OWNER TABLE STATUS NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ----- -------- ---------- ---------- ------------ ---------- ---------- -----------
SCOTT T1 VALID 12 4 4 7533 0 41
SQL> ANALYZE TABLE T1 DELETE STATISTICS;
表已分析。
SQL> select OWNER,TABLE_NAME,STATUS,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,CHAIN_CNT,AVG_ROW_LEN from dba_tables where table_name='T1';
OWNER TABLE STATUS NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ----- -------- ---------- ---------- ------------ ---------- ---------- -----------
SCOTT T1 VALID
SQL> exec dbms_stats.gather_table_stats('SCOTT','T1');
PL/SQL 過程已成功完成。
SQL> select OWNER,TABLE_NAME,STATUS,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,CHAIN_CNT,AVG_ROW_LEN from dba_tables where table_name='T1';
OWNER TABLE STATUS NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ----- -------- ---------- ---------- ------------ ---------- ---------- -----------
SCOTT T1 VALID 12 4 0 0 0 39
結論:可以發現analyze 可以收集dba_tables 表里的統計信息,而dbms_stats.gather_table_stats 只能收集到 AVG_ROW_LEN
SQL> create unique index ii on t1(empno);
索引已創建。
SQL> select OWNER,INDEX_NAME,INDEX_TYPE,COMPRESSION,BLEVEL,STATUS,NUM_ROWS,DISTINCT_KEYS,LEAF_BLOCKS,DEGREE from dba_indexes where table_name='T1'
OWNER INDEX_NAME INDEX_TYPE COMPRESS BLEVEL STATUS NUM_ROWS DISTINCT_KEYS LEAF_BLOCKS DEGREE
---------- ------------------------------ --------------------------- -------- ---------- -------- ---------- ------------- ----------- ----------
SCOTT II NORMAL DISABLED 0 VALID 12 12 1 1
SQL> ANALYZE TABLE T1 DELETE STATISTICS;
表已分析。
SQL> select OWNER,TABLE_NAME,STATUS,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,CHAIN_CNT,AVG_ROW_LEN from dba_tables where table_name='T1';
OWNER TABLE STATUS NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ----- -------- ---------- ---------- ------------ ---------- ---------- -----------
SCOTT T1 VALID
結論:刪除表上的統計信息,那么定義在此表上的索引的統計信息也一起刪除
SQL> analyze table t1 validate structure cascade;
表已分析。
SQL> select OWNER,TABLE_NAME,STATUS,NUM_ROWS,BLOCKS,EMPTY_BLOCKS,AVG_SPACE,CHAIN_CNT,AVG_ROW_LEN from dba_tables where table_name='T1';
OWNER TABLE STATUS NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ----- -------- ---------- ---------- ------------ ---------- ---------- -----------
SCOTT T1 VALID
結論:分析表結構的時候,不會收集統計信息
SQL> analyze table t1 list chained rows ;
analyze table t1 list chained rows
*
第 1 行出現錯誤:
ORA-01495: 未找到指定的鏈接行表
SQL> @?/rdbms/admin/utlchain.sql
表已創建。
SQL> Analyze table t1 list chained rows;
表已分析。
SQL> select *From CHAINED_ROWS;
未選定行
結論:如果不指定表名,那么必須手動創建默認的表 CHAINED_ROWS
SQL> drop table t1 purge;
表已刪除。
SQL> create table t1 as select *From emp;
表已創建。
SQL> create index ii on t1(empno);
索引已創建。
SQL> select *From V$OBJECT_USAGE
2 ;
未選定行
SQL> alter index ii monitoring usage;
索引已更改。
SQL> analyze table t1 compute statistics;
表已分析。
SQL> alter index ii monitoring usage;
索引已更改。
SQL> select *From V$OBJECT_USAGE
2 ;
INDEX_NAME TABLE MON USE START_MONITORING END_MONITORING
------------------------------ ----- --- --- ------------------- -------------------
II T1 YES NO 03/15/2013 15:31:13
SQL> exec dbms_stats.gather_table_stats('SCOTT','T1');
PL/SQL 過程已成功完成。
SQL> select *From V$OBJECT_USAGE ;
INDEX_NAME TABLE MON USE START_MONITORING END_MONITORING
------------------------------ ----- --- --- ------------------- -------------------
II T1 YES NO 03/15/2013 15:31:13
結論:dbms_stats.gather_table_stats 在收集統計信息的時候會收集索引的統計信息,但是analyze在收集統計信息的時候不會收集索引的統計信息,但是我們一定要記住,使用dbms_stats收集的統計信息是給基於成本的優化器使用的,但是analyze 收集的統計信息是 是dba_table 里,analyze 命令可以驗證表的結構 validate,可以檢查行遷移行連接
ANALYZE - 收集與數據庫有關的統計
SYNOPSIS
ANALYZE [ VERBOSE ] [ table [ (column [, ...] ) ] ]
DESCRIPTION 描述
ANALYZE 收集有關 PostgreSQL 表的內容的統計,然后把結果保存在系統表 pg_statistic 里。隨后,查詢規划器就可以使用這些統計幫助判斷查詢的最有效的規划。
如果沒有參數,ANALYZE 檢查在當前數據庫里的所有表。 如果有參數,ANALYZE 只檢查那個表。 你還可以給出一列字段名字,這個時候只收集那些字段的統計信息。
PARAMETERS 參數
- VERBOSE
-
打開處理過程信息的顯示。 - table
-
要分析的特定表(可能用模式名修飾)的名字。缺省是當前數據庫里所有表。 - column
-
要分析的特定字段的名字。缺省是所有字段。
OUTPUTS 輸出
如果聲明了 VERBOSE,ANALYZE 發出進度信息,表明當前正在處理的是哪行。 同時打印有關改表的很多其它信息。
NOTES 注意
周期性地運行 ANALYZE,或者在對表的大部分內容做了更改之后馬上運行它是個好習慣, 准確的統計信息將幫助規划器選擇最合適的查詢規划,並因此而改善查詢處理的速度。 一種比較經常采用的策略是每天在低負荷的時候運行一次 VACUUM [vacuum(7)] 和 ANALYZE。
和 VACUUM FULL 不同的是, ANALYZE 只需要在目標表上有一個讀取鎖, 因此它可以和表上的其它活動並行地運行。
收集的統計信息通常包括一個每字段最常用數值的列表以及一個包線圖,顯示每個字段里數據的近似分布。 如果 ANALYZE 認為它們都沒有什么用, (比如,在一個唯一鍵字的字段上沒有公共的數值)或者是該字段數據類型不支持相關的操作符, 那么它們都可以忽略。在 Chapter 21 ``Routine Database Maintenance'' 中有關於統計的更多信息。
對於大表,ANALYZE 采集表內容的一個隨機的抽樣做統計,而不是檢查每一行。 這樣就保證了即使是在很大的表上,我們也只需要很少的一些時間就可以完成分析。 不過,要注意的是統計只是近似的結果,而且每次運行ANALYZE都會導致 EXPLAIN 顯示的規划器的預期開銷有一些小變化, 即使表內容實際上沒有改變也這樣。在很小的概率的情況下,這個不確定的行為會導致查詢優化器在不同 ANALYZE 之間選擇不同的查詢規划。為了避免這個問題,可以提高 ANALYZE 收集的統計數量,像下面描述的那樣。
分析的廣度可以通過用調整 default_statistics_target 參變量, 或者是以每字段為基礎通過用 ALTER TABLE ... ALTER COLUMN ... SET STATISTICS (參閱 ALTER TABLE [alter_table(7)]) 設置每字段的統計目標來控制。目標數值設置最常用數值列表中的記錄的最大數目以及包線圖中的最大塊數。 缺省的目標數值是 10,不過我們可以調節這個數值獲取規划器計算精度和 ANALYZE 運行所需要的時間以及 pg_statistic 里面占據的空間數目之間的平衡。 特別是,把統計目標設置為零就關閉了該字段的統計收集。 這么做對那些從來不參與到查詢的 WHERE,GROUP BY,或者 ORDER BY 子句里的字段是很有用的,因為規划器不會使用到這樣的字段上的統計。
在被分析的字段中最大的統計目標決定為統計采樣的表中的行的數目。 增大目標會導致做 ANALYZE 的時候成比例地增大對時間和空間的需求。
————————————————
https://blog.csdn.net/wll_1017/article/details/8672227