1. 統計信息查看php
2.1 分析工具選擇服務器
2.2 分析前作index重建session
2.3 分析某數據表,能夠在PL/SQL的command window下執行的架構
2.4 分析SCHEMA,在SQLPLUS中進行的oracle
2.5 dbms_stats.gather_schema_stats詳解工具
2.6 初始化參數statistics_level與oracle默認統計信息收集JOB的關係性能
3.1 建立新的統計信息收集PROC、JOB,每週末執行一次
4.3按表收集統計信息:改變了核心SQL的執行計劃---OK
4.4統計信息收集實戰的重要結論(oracle公司技術人員推薦)
SQL> select COLUMN_NAME,NUM_DISTINCT,DENSITY,SAMPLE_SIZE,AVG_COL_LEN from DBA_TAB_COL_STATISTICS where table_name='TB1';
SQL> select GLOBAL_STATS from dba_tables where table_name='TB1';
若是是NO,則立刻要分析統計信息。
查看某表最後一次統計信息收集時間:
SQL> select to_char(LAST_ANALYZED,'fmYYYY-MM-DD HH24:MI:SS') from dba_tables where WNER='PLATFORM_DEV' and TABLE_NAME='T_USER';
查看某索引最後一次統計信息收集時間:查dba_indexes、user_indexes的LAST_ANALYZED.
dbms_stats能夠並行分析
dbms_stats有自動分析的功能(alter table monitor )
analyze 分析統計信息,不許確----some times
按表重建索引:
SQL> select 'alter index platform_dev.'||INDEX_NAME||' rebuild online;' from dba_indexes where wner='PLATFORM_DEV' and TABLE_NAME='T_SSO_SESSION';
按用戶(schema)重建索引:
SQL> select 'alter index platform_dev.'||INDEX_NAME||' rebuild online;' from dba_indexes where wner='PLATFORM_DEV';
缺省方式----最經常使用的方式:
SQL> EXECUTE DBMS_STATS.GATHER_TABLE_STATS(
OWNNAME => 'LK',
TABNAME => 'TB1' ,
ESTIMATE_PERCENT => NULL ,
METHOD_OPT => 'FOR ALL INDEXED COLUMNS' ,
CASCADE => TRUE);
------整表全分析(全粒度),注意,必加cascade=true,不然相關索引可能不統計。
SQL> begin
DBMS_STATS.GATHER_TABLE_STATS(ownname => 'PLATFORM_DEV',tabname => 'T_OPERATION_LOG', CASCADE => TRUE);
end;
/
PL/SQL:
begin
dbms_stats.gather_schema_stats(ownname =>'PLATFORM_DEV',estimate_percent => 5,cascade=>true,degree=>5);
end;
/
SQLPLUS:
----資源耗用大,只能在服務器本機sqlplus中執行。
SQL> exec dbms_stats.gather_schema_stats(ownname =>'LK',estimate_percent => 5,cascade=>true,degree=>5);
estimate_percent選項:容許Oracle的dbms_stats在收集統計數據時,自動估計要採樣的一個segment的最佳百分比:
estimate_percent => dbms_stats.auto_sample_size ---這是它的缺省值
estimate_percent=>100 ---徹底統計
cascade選項:遞歸統計,統計相關表對應的索引
cascade=> TRUE
degree選項:決定並行度.默認值爲null
options參數
options=>"gather"——從新分析整個架構(Schema)。
options=>"gather empty" -----收集沒有分析過的表的統計信息
options=>"gather stale" ----從新分析修改量超過10%的表(即增、刪、改)。
options=>"gather auto" ----從新分析當前沒有統計的對象,以及統計數據過時(變髒)的對象。注意,使用gather auto相似於組合使用gather stale和gather empty。
method_opt參數
適合在表和索引數據發生變化時刷新統計數據,也適合用於判斷哪些列須要直方圖(histograms)。
method_opt=>'for all columns size skewonly'
method_opt=>'for all columns size repeat' ----按期從新分析統計數據時,使用它,從新分析任務所消耗的資源就會少一些。它只會爲現有的直方圖從新分析索引,再也不搜索其餘直方圖機會。-----觸發了BUG!別用此項!
method_opt=>'for all columns size auto' -----ORACLE公司推薦設置值
Ø Sys用戶,找到默認統計信息收集JOB:
select OWNER,PROGRAM_NAME,job_action,job_name, state from Dba_Scheduler_Jobs where JOB_NAME ='GATHER_STATS_JOB'
Ø 初始化參數statistics_level三種狀態(BASIC、TYPICAL或ALL)
statistics_level=basic時,oracle關閉默認統計信息收集JOB中全部性能數據的收集,也即若要關閉AWR或statspack收集,只要設置alter system set statistics_level=basic;就好了。
statistics_level=typical的時候,除了plan_executetion_statistics和OS Statistics不能收集外,其餘的均可以收集,如要要收集這個兩項,必須設置statistics_level=all;
/////可選的方法---禁用默認的統計信息收集JOB,但不提倡
Sys用戶,將默認統計信息收集JOB禁用:
SQL> BEGIN
DBMS_SCHEDULER.DISABLE('GATHER_STATS_JOB');
END; ----再次啓用就用DBMS_SCHEDULER.ENABLE命令
複查是否真已被禁用:
SQL> SELECT OWNER,JOB_NAME,ENABLED FROM DBA_SCHEDULER_JOBS WHERE JOB_NAME = 'GATHER_STATS_JOB'; ---- 此時ENABLED應爲FALSE
/////可選的方法---禁用默認的統計信息收集JOB,但不提倡,結束
Ø Sys用戶建立週末統計信息收集存儲過程
create or replace procedure PROC_STATISTICS_GATHER_WEEKEND is
begin
---gather statistics of schema:LK
dbms_stats.gather_schema_stats(ownname =>'LK',
estimate_percent => 30,
cascade=>true,degree=>5);
----repeat above sentence for other schema.
end;
----參數method_opt=>'for all columns size repeat'是否有問題 ,不顯式指定而用默認值最好。
Ø Sys用戶建立週末統計信息收集JOB
begin
dbms_scheduler.create_job (
job_name => 'JOB_STATISTICS_GATHER_WEEKEND',
job_type => 'STORED_PROCEDURE',
job_action => 'SYS.PROC_STATISTICS_GATHER_WEEKEND',
start_date => to_date('2010-08-22 04:00:00','fmYYYY-MM-DD HH24:MI:SS'),
repeat_interval => 'FREQ=DAILY;INTERVAL=7',
comments => 'author: liukan');
end;
----注:每7天一次,第一次是2010-08-22 04:00:00,
Ø Sys開啓ENABLE上面的JOB
begin
dbms_scheduler.enable('JOB_STATISTICS_GATHER_WEEKEND');
end;
Ø Sys手動試運行上面的JOB
begin
dbms_scheduler.run_job(job_name => 'JOB_STATISTICS_GATHER_WEEKEND',
use_current_session => TRUE);
end;
Sys用戶:
select job_name,job_action,state,to_char(START_DATE,'fmYYYY-MM-DD HH24:MI:SS') START_DATE, to_char(NEXT_RUN_DATE,'fmYYYY-MM-DD HH24:MI:SS') NEXT_RUN_DATE from user_scheduler_jobs;
select 'exec DBMS_STATS.GATHER_TABLE_STATS(ownname => '||chr(39)||'PLATFORM_DEV'||chr(39)||',tabname => '||chr(39)||table_name||chr(39)||',CASCADE => TRUE,degree => 5);' from user_tables;
create or replace procedure PROC_STATISTICS_GATHER_WEEKEND is
begin
dbms_stats.gather_schema_stats(ownname =>'PLATFORM_DEV',
estimate_percent => 50,
method_opt=>'for all columns size repeat',
cascade=>true,degree=>5);
end;
----它的執行致使友商網主站庫最最核心的(用戶登陸)SQL沒法走最佳執行計劃。
命令1:
exec dbms_stats.gather_schema_stats(ownname =>'PLATFORM_DEV',estimate_percent => 30,cascade=>true,degree=>5);
命令2:
exec dbms_stats.GATHER_SCHEMA_STATS(ownname=>'PLATFORM_DEV',estimate_percent => 30,method_opt=>'for all indexed columns',options=>'GATHER',cascade=>TRUE);
命令3:
exec dbms_stats.gather_schema_stats(ownname => 'PLATFORM_DEV', estimate_percent => 30, method_opt => 'for all columns size skewonly', cascade=>true,degree => 5);
命令4:
exec dbms_stats.gather_schema_stats(ownname => 'PLATFORM_DEV', estimate_percent => 30, method_opt => 'for all columns size skewonly', cascade=>true,degree => 5);
這些命令都沒用,在重建完全部索引後,再執行這些語句也沒用,核心的(用戶登陸)SQL仍是沒法走最佳執行計劃。
exec DBMS_STATS.GATHER_TABLE_STATS(ownname => 'PLATFORM_DEV',tabname => 'T_USER', CASCADE => TRUE,degree => 5);
exec DBMS_STATS.GATHER_TABLE_STATS(ownname => 'PLATFORM_DEV',tabname => 'T_CORPORATION_USER', CASCADE => TRUE,degree => 5);
……
核心的(用戶登陸)SQL走了最佳執行計劃!
dbms_stats.gather_schema_stats可能很差用,還不如:
1. 每三個月或每半年(根據數據變動的頻繁度決定)利用例行更新停機時間,整理主要表的存儲結構(move tablespace可同一tbs)、重建全部索引(rebuild無online選項),在此基礎上手工按schema收集統計信息,而後,密切跟蹤數據庫性能。+
2. 平時的統計信息收集由oracle自帶的自動統計信息收集機制完成+
3. 發現慢SQL,可重點考慮重建與慢SQL相關的表的索引、從新收集相關表的統計信息(DBMS_STATS.GATHER_TABLE_STATS)+
/////////////////////
select 'exec DBMS_STATS.GATHER_TABLE_STATS(ownname => ' || chr(39) ||
'PLATFORM_DEV' || chr(39) || ',tabname => ' || chr(39) || table_name ||
chr(39) || ',estimate_percent =>30,CASCADE => TRUE,degree => 5);'
from user_tables t where t.table_name not like '%$%';
////////////////////
4. 最核心、最頻繁執行、且並不是程序複雜拼裝的SQL,應加HINT,以強制其執行計劃。
5. 重要、咽喉的、核心的SQL以存儲過程或視圖形式存於oracle數據庫中,以方便快速SQL調優、故障解決。