Oracle 表分析


ANALYZE TABLE SeikyuTbl COMPUTE Statistics FOR TABLE FOR ALL COLUMNS FOR ALL INDEXES ; 

一、優化器的優化方式 
Oracle的優化器共有兩種的優化方式,即基於規則的優化方式(Rule-Based Optimization,簡稱為RBO)和基於代價的優化方式(Cost-Based Optimization,簡稱為CBO)。 
1、CBO方式:依詞義可知,它是看語句的代價(Cost)了,這里的代價主要指Cpu和內存。優化器在判斷是否用這種方式時,主要參照的是表及索引的統計信息。統計信息給出表的大小、有少行、每行的長度等信息。這些統計信息起初在庫內是沒有的,是你在做analyze后才出現的,很多的時侯過期統計信息會令優化器做出一個錯誤的執行計划,因些我們應及時更新這些信息。在Oracle8及以后的版本,Oracle列推薦用CBO的方式。 
2、RBO方式:優化器在分析SQL語句時,所遵循的是Oracle內部預定的一些規則。比如我們常見的,當一個where子句中的一列有索引時去走索引。 
我們要明了,不一定走索引就是優的 ,比如一個表只有兩行數據,一次IO就可以完成全表的檢索,而此時走索引時則需要兩次IO,這時對這個表做全表掃描(full table scan)是最好的。 
二、優化器的優化模式(Optermizer Mode) 
優化模式包括Rule,Choose,First rows,All rows這四種方式: 
Rule:不用多說,即走基於規則的方式。 
Choolse:默認的情況下Oracle用的便是這種方式。指的是當一個表或或索引有統計信息,則走CBO的方式,如果表或索引沒統計信息,表又不是特別的小,而且相應的列有索引時,那么就走索引,走RBO的方式。 
First Rows:它與Choose方式是類似的,所不同的是當一個表有統計信息時,它將是以最快的方式返回查詢的最先的幾行,從總體上減少了響應時間。 
All Rows:也就是我們所說的Cost的方式,當一個表有統計信息時,它將以最快的方式返回表的所有的行,從總體上提高查詢的吞吐量。沒有統計信息則走基於規則的方式。 
三、如何設定選用哪種優化模式 
1、Sessions級別 
通過SQL> ALTER SESSION SET OPTIMIZER_MODE=?;來設定。 
2、Instance級別 
我們可以通過在init.ora文件中設定OPTIMIZER_MODE=RULE、OPTIMIZER_MODE=CHOOSE、OPTIMIZER_MODE=FIRST_ROWS、OPTIMIZER_MODE=ALL_ROWS去選用以上所提的四種方式,如果你沒設定OPTIMIZER_MODE參數則默認用的是Choose這種方式。 
3、語句級別 
這些需要用到Hint,比如: 
SELECT /*+ RULE */ a.userid,b.name,b.depart_name FROM tf_f_yhda a,tf_f_depart b WHERE a.userid=b.userid; 
四、與CBO相關統計信息的獲取(analyze 與 dbms_stats 使用) 
壹、analyze 使用 
1、功能 
a)搜集和刪除索引、表和簇的統計信息 
b)驗證表、索引和簇的結構 
c)鑒定表和簇和行遷移和行聯接 
d)針對analyze的搜集和刪除統計信息功能而言,oracle推薦使用DBMS_STATS包來搜集優化信息,DBMS_STATS可以並行的搜集信息,可以搜集分區表的全局信息,進一步來說,按成本的優化器只會使用DBMS_STATS包所統計出來的信息。 
2、可供分析的對象 
INDEX:對索引進行分析,分析的結果會放在USER_INDEXES, ALL_INDEXES,或 DBA_INDEXES中 
分析的內容: 
Depth of the index from its root block to its leaf blocks (BLEVEL) 
Number of leaf blocks (LEAF_BLOCKS) 
Number of distinct index values (DISTINCT_KEYS) 
Average number of leaf blocks for each index value (AVG_LEAF_BLOCKS_PER_KEY) 
Average number of data blocks for each index value (for an index on a table) (AVG_DATA_BLOCKS_PER_KEY) 
Clustering factor (how well ordered the rows are about the indexed values) (CLUSTERING_FACTOR) 
TABLE:對表進行分析,分析的結果會放在USER_TABLES, ALL_TABLES, and DBA_TABLES表中,在分析表的時候,oracle也會分析基於函數的index所引用的表達式 
分析的內容: 
Number of rows (NUM_ROWS) 
Number of data blocks below the high water mark (that is, the number of data blocks that have been formatted to receive data, regardless whether they currently contain data or are empty) (BLOCKS) 
Number of data blocks allocated to the table that have never been used (EMPTY_BLOCKS) Average available free space in each data block in bytes (AVG_SPACE) 
Number of chained rows (CHAIN_COUNT) Average row length, including the row's overhead, in bytes (AVG_ROW_LEN) 
PARTITION | SUBPARTITION:對分區表或索引進行分析 
CLUSTER:對簇進行分析,分析的結果會放在ALL_CLUSTERS, USER_CLUSTERS and DBA_CLUSTERS. 
compute_statistics_clause 
語法:COMPUTE [ SYSTEM ] STATISTICS [for_clause] 
對分析對像進行精確的統計,然后把信息存儲的數據字典中。可以選擇對表或對字段進行分析。 
computed和estimated這兩種方式的統計數據都被優化器用來影響sql的執行計划 
如果指定system選項就只統計系統產生的信息 
for_clause FOR TABLE:只統計表 FOR COLUMNS:只統計某個字段 FOR ALL COLUMNS:統計所有字段 FOR ALL INDEXED COLUMNS:統計索引的所有字段 
estimate_statistics_clause 
ESTIMATE [ SYSTEM ] STATISTICS [for_clause][SAMPLE integer { ROWS | PERCENT }] 
只是對部分行做一個大概的統計。適用於大表 
SAMPLE:指定具體統計多少行,如果忽略這個參數的話,oracle會默認為1064行 
ROWS causes:行數 Oracle to sample integer rows of the table or cluster or integer entries from the index. The integer must be at least 1. 
PERCENT causes:百分數 
validation_clauses 
分析REF或是對像的結構 
EG:ANALYZE TABLE employees VALIDATE STRUCTURE CASCADE; 
ANALYZE TABLE customers VALIDATE REF UPDATE; 
3、分析表的限制 
a)不可以分析數據字典表 
b)不可以分析擴展表,但可以用DBMS_STATS來實現這個目的 
c)不可以分析臨時表 
d)不可以計算或估計下列字段類型REFs, varrays, nested tables, LOBs (LOBs are not analyzed, they are skipped), LONGs, or object types. 
貳、dbms_stats 使用 
Dbms_stats是oracle8i新增的程序包,它使統計數據的生成和處理更加方便。 
--參數 
estimate_percent        --估算抽樣百分比 
method_opt for table    --只統計表  
for all indexed columns --只統計有索引的表列 
for all indexes         --只分析統計相關索引 
--創建統計信息歷史保留表 
sql> exec dbms_stats.create_stat_table(ownname => 'scott',stattab => 'stat_table') ; 
pl/sql procedure successfully completed 
--導出整個scheme的統計信息 
sql> exec dbms_stats.export_schema_stats(ownname => 'scott',stattab => 'stat_table') ; 
pl/sql procedure successfully completed 
--分析scheme 
Exec dbms_stats.gather_schema_stats( 
ownname => 'scott', 
options => 'GATHER AUTO', 
estimate_percent => dbms_stats.auto_sample_size, 
method_opt => 'for all indexed columns ', 
degree => 6 ) 
--分析表 
sql> exec dbms_stats.gather_table_stats(ownname => 'scott',tabname => 'work_list',estimate_percent => 10,method_opt=> 'for all indexed columns') ; 
pl/sql procedure successfully completed 
--分析索引 
SQL> exec dbms_stats.gather_index_stats(ownname => 'crm2',indname => 'IDX_ADM_PERMISSION_PID_MID',estimate_percent => '10',degree => '4') ; 
pl/sql procedure successfully completed 
--如果發現執行計划走錯,刪除表的統計信息 
SQL>dbms_stats.delete_table_stats(ownname => 'scott',tabname => 'work_list') ; 
pl/sql procedure successfully completed 
--導入表的歷史統計信息 
sql> exec dbms_stats.import_table_stats(ownname => 'scott',tabname => 'work_list',stattab => 'stat_table') ; 
pl/sql procedure successfully completed 
--如果進行分析后,大部分表的執行計划都走錯,需要導回整個scheme的統計信息 
sql> exec dbms_stats.import_schema_stats(ownname => 'scott',stattab => 'stat_table'); 
pl/sql procedure successfully completed 
--導入索引的統計信息 
SQL> exec dbms_stats.import_index_stats(ownname => 'crm2',indname => 'IDX_ADM_PERMISSION_PID_MID',stattab => 'stat_table') 
--檢查是否導入成功 
SQL> select table_name,num_rows,a.blocks,a.last_analyzed from all_tables a where a.table_name='WORK_LIST'; 
TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED 
------------------------------ ---------- ---------- ------------- 
WORK_LIST 4005 186 2007-10-12 15 
叄、analyze dbms_stats 區別 
自從Oracle8.1.5引入dbms_stats包,Experts們便推薦使用dbms_stats取代analyze。理由如下 
1,dbms_stats可以並行分析 
2,dbms_stats有自動分析的功能(alter table monitor ) 
3,analyze 分析統計信息的不准確some times 
如果想分析整個用戶或數據庫,還可以采用工具包,可以並行分析:Dbms_utility(8i以前的工具包) Dbms_stats(8i以后提供的工具包),如:(以下兩個dbms_stats最常用) 
dbms_stats.gather_schema_stats(User,estimate_percent=>100,cascade=> TRUE); 
dbms_stats.gather_table_stats(User,TableName,degree => 4,cascade => true); 
總結: 
1、DBMS_STATS的優點 
a) 可以並行進行,對多個用戶,多個Table 
b) 可以得到整個分區表的數據和單個分區的數據。 
c) 可以在不同級別上Compute Statistics:單個分區,子分區,全表,所有分區 
d) 可以倒出統計信息 
e) 可以用戶自動收集統計信息 
f) 對於分區表,建議使用DBMS_STATS,而不是使用Analyze語句 
g) 對於oracle 9里面的External Table,Analyze不能使用,只能使用DBMS_STATS來收集信息 
2、DBMS_STATS的缺點 
a) 不能Validate Structure 
b) 不能收集CHAINED ROWS, 不能收集CLUSTER TABLE的信息,這兩個仍舊需要使用Analyze語句 
c) DBMS_STATS 默認不對索引進行Analyze,因為默認Cascade是False,需要手工指定為True 
五、應用一例: 
1、按用戶分析 
BEGIN                                                                         
DBMS_STATS.GATHER_SCHEMA_STATS(OWNNAME=>   'SCOTT'   ,   CASCADE=>   TRUE);  
END ;                  
2、單表分析 
ANALYZE   TABLE   MYTABLE   COMPUTE   STATISTICS;         
獲取分析語句: 
SELECT   'ANALYZE   TABLE   '||TABLE_NAME||'   COMPUTE   STATISTICS;' FROM   USER_TABLES;         
3、用途舉例: 
select a.table_name, a.num_rows from user_tables a where a.num_rows = 0; 
--統計記錄數據為空的表,如果事先未進行數據分析,則統計結果可能會不正確 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM