Oracle 性能優化 — 統計數據收集


ORACLE優化器的優化方式有兩大類,即基於規則的優化方式(Rule-Based Optimization,簡稱為RBO)和基於代價的優化方式(Cost-Based Optimization,簡稱為CBO)。

A、 RBO方式:優化器在分析SQL語句時,更據數據庫中表和索引等定義信息,遵循的是Oracle內部預定的一些規則。比如我們常見的:當一個where子句中的一列有索引時去走索引而不走全表掃描。
B、 CBO方式:依詞義可知,它是看語句的代價(Cost)了。基於代價的查詢,數據庫根據搜集的表和索引的數據的統計信息(統計信息通過analyze 命令或者使用dbms_stats包來搜集)綜合來決定選取一個數據庫認為最優的執行計划(實際上不一定最優) 。統計信息給出表的大小 、有多少行、每行的長度等信息。
注意:這些統計信息起初在庫內是沒有的,是根據 analyze 命令或者dbms_stats包來定期搜集后才出現的,所以很多的時侯過期統計信息會令優化器做出一個錯誤的執行計划,因些我們應及時更新這些信息。為了使用基於成本的優化器(CBO) , 你必須經常運行analyze或dbms_stats命令,以增加數據庫中的對象統計信息(object statistics)的准確性。
在Oracle8及以后的版本,Oracle強列推薦用CBO的方式。

1. 如何查看對象統計信息(object statistics)

對CBO模式,對象統計信息至關重要。如何查看對象統計信息(object statistics)?
Oracle中關於表的統計信息是在數據字典中的,可以下SQL查詢到,eg:
SELECT table_name,num_rows, blocks, empty_blocks AS empty, avg_space, chain_cnt, avg_row_len
FROM dba_tables
WHERE owner = ‘ONT’
AND table_name = ‘OE_ORDER_LINES_ALL’;
TABLE_NAME NUM_ROWS BLOCKS EMPTY AVG_SPACE CHAIN_CNT AVG_ROW_LEN
OE_ORDER_LINES_ALL 5344 505 5 0 0 441
可以看到數據字典中統計到的該表有5344筆記錄,我們下SQL驗證一下:
select count(*) from apps.OE_ORDER_LINES_ALL;
發現返回是16518筆記錄,可見這個表的統計信息是比較陳舊的,真實數據與統計到的數據有較大的差別。在這種情況下,如果某個View用到此Table,且系統使用CBO的方式,則可能導致Oracle的optimizer給出效率低下的執行計划。

此時可以用ANALYZE去重新統計OE_ORDER_LINES_ALL這個表,可以下SQL:
ANALYZE TABLE ONT.OE_ORDER_LINES_ALL COMPUTE STATISTICS;
再次Query數據字典:
TABLE_NAME NUM_ROWS BLOCKS EMPTY AVG_SPACE CHAIN_CNT AVG_ROW_LEN
OE_ORDER_LINES_ALL 16518 1530 1035 865 257 643

發現此時的信息已是最新的了。有了比較正確的統計信息,optimizer才能給出高效的執行計划。

2. 並發請求: 統計數據收集模式(FNDGSCST) / Gather Schema Statistics

Oracle ERP中有幾個與Gather有關的標准Request:
Gather All Column Statistics –FND_STATS.GATHER_ALL_COLUMN_STATS()
Gather Column Statistics –FND_STATS.GATHER_COLUMN_STATS()
Gather Schema Statistics –FND_STATS.GATHER_SCHEMA_STATS()
Gather Table Statistics –FND_STATS.GATHER_TABLE_STATS()
查看FND_STATS 這個Package的寫法,其實它就是在調用Oracle DB中Standard的Package dbms_stats 中的某些Function。
Oracle DB中常用的Gather有以下一些,DBA也可以直接在Database級別上定期Run這些Function,以便能讓Oracle統計到最新的數據庫狀況:
dbms_stats.gather_database_stats();
dbms_stats.gather_schema_stats();
dbms_stats.gather_table_stats();
dbms_stats.gather_index_stats();

Oracle CBO需要系統定期分析統計表/索引。 只有這樣CBO才能使用正確的SQL訪問路徑,提高查詢效率。 因此在Instance Level的optimizer_mode = choose ,定期運行ANALYZE 或dbms_stats是非常重要的,尤其是當上次統計后,數據量已發生較大變化之后。
注意:統計操作是很耗資源的動作,要在系統Loading小的時候進行。

 


免責聲明!

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



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