【DB筆試面試628】Oracle的統計信息包括哪幾種類型?

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

         題目         部分

Oracle的統計信息包括哪幾種類型?程序員


     
         答案部分          



Oracle數據庫裏的統計信息是一組存儲在數據字典裏,且從多個維度描述了數據庫裏對象的詳細信息的一組數據。Oracle數據庫工做在CBOCost Based Optimization,基於代價的優化器模式下,優化器根據數據字典中記錄的對象統計信息評估SQL語句不一樣執行計劃的成本從而找到最優或者是相對最優的執行計劃。因此,能夠說,SQL語句的執行計劃由統計信息來決定,若沒有統計信息則會採起動態採樣的方式來生成執行計劃。統計信息決定着SQL的執行計劃的正確性,屬於SQL執行的指導思想。若統計信息不許確,則會致使表的訪問方式(例如應該使用索引,可是選擇了全表掃描)、表與表的鏈接方式出現問題(例如應該使用HJ,可是使用了NL鏈接),從而致使CBO選擇錯誤的執行計劃。面試

統計信息主要包括6種類型,其中表、列和索引的統計信息也能夠統稱爲普通對象的統計信息,以下所示:sql

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

查詢表統計信息的SQL以下所示:數據庫

 1SELECT D.NUM_ROWS, --表中的記錄數
2       D.BLOCKS, --轟中數據所佔的數據塊數
3       D.EMPTY_BLOCKS, --表中的空塊數
4       D.AVG_SPACE, --數據塊中平均的,使用空間
5       D.CHAIN_CNT, --表中行鏈接和行遷移的數量
6       D.AVG_ROW_LEN, --每條記錄的平均長度
7       D.STALE_STATS, --統計信息是否過時
8       D.LAST_ANALYZED --最近一次蒐集統計信息的時間
9  FROM DBA_TAB_STATISTICS D  --DBA_TAB_STATISTICS DBA_TABLES
10 WHERE D.TABLE_NAME = 'CUSTOMERS';
     

查詢表上列的統計信息的SQL以下所示:服務器

 1SELECT D.COLUMN_NAME,
2       D.NUM_DISTINCT, --惟一值的個數
3       D.LOW_VALUE, --列上的最小值
4       D.HIGH_VALUE, --列上的最大值
5       D.DENSITY, --若不存在柱狀圖的話,則表示選擇率因子(密度)=1/(NDV)
6       D.NUM_NULLS, --空值的個數
7       D.NUM_BUCKETS, --直方圖的BUCKETS個數
8       D.HISTOGRAM --直方圖的類型
9  FROM DBA_TAB_COLUMNS D  --DBA_TAB_COL_STATISTICS
10 WHERE TABLE_NAME = 'CUSTOMERS';
     


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


關於上表中須要注意的幾點:微信

(一)索引統計信息網絡

BLEVEL存儲的就是目標索引的層級,它表示的是從根節點到葉子塊的深度,BLEVELCBO用於計算訪問索引葉子塊的成本。BLEVEL的值越大,則從根節點到葉子塊所須要訪問的數據塊的數量就會越多,耗費的I/O就會越多,訪問索引的成本就會越大。BLEVEL的值從0開始算起,當BLEVEL的值爲0時,表示該B樹索引只有一層,且根節點和葉子塊就是同一個塊。在Oracle數據庫裏,若是要下降目標B樹索引的層級,那麼只能經過REBUILD該索引的方式來實現。app

(二)列的統計信息ide

列的統計信息用於描述Oracle數據庫裏列的詳細信息,包含了列的DISTINCT值的數量、列的NULL值的數量、列的最小值、列的最大值等一些典型維度。這些列統計信息其實是存儲在數據字典基表SYS.HIST_HEAD$中,能夠經過數據字典DBA_TAB_COL_STATISTICSDBA_PART_COL_STATISTICSDBA_SUBPART_COL_STATISTICS來分別查看錶、分區表的分區和分區表的子分區的列統計信息。在這些數據字典中的字段NUM_DISTINCT存儲的就是目標列的DISTINCT值的數量。CBONUM_DISTINCT的值來評估用目標列作等值查詢的可選擇率(Selectivity)。CBO會用NUM_NULLS的值來調整對有NULL值的目標列作等值查詢的可選擇率。函數

數據字典中的字段DENSITYNUM_BUCKETS分別存儲的是目標列的密度和所用桶的數量,這兩個維度僅和直方圖有關。在沒有直方圖統計信息時,DENSITY的值就等於I/NUM_DISTINCT;在有頻率直方圖的時,DENSITY的值就等於1/(2*(NUM_ROWS-NUM_NULLS))。示例以下:

1CREATE TABLE T_MD_20170606_LHR AS SELECT ROWNUM ID,ROWNUM SAL FROM DUAL CONNECT BY LEVEL<=10000;
2UPDATE T_MD_20170606_LHR SET SAL=5000 WHERE SAL BETWEEN 6 AND 9995;  --9990 
3UPDATE T_MD_20170606_LHR SET SAL='' WHERE SAL BETWEEN 2 AND 3;  --2 
     

在無直方圖的狀況下:

 1LHR@orclasm > EXEC DBMS_STATS.GATHER_TABLE_STATS(USER,'T_MD_20170606_LHR',CASCADE=>TRUE,METHOD_OPT=>'FOR ALL COLUMNS SIZE 1');
2
3PL/SQL procedure successfully completed.
4
5LHR@orclasm > SET LINESIZE 120
6LHR@orclasm > SELECT D.COLUMN_NAME,D.NUM_DISTINCT,D.NUM_NULLS,D.NUM_BUCKETS,D.HISTOGRAM,D.DENSITY FROM DBA_TAB_COLUMNS D WHERE D.TABLE_NAME = 'T_MD_20170606_LHR';
7
8
9COLUMN_NAME                    NUM_DISTINCT  NUM_NULLS NUM_BUCKETS HISTOGRAM          DENSITY
10------------------------------ ------------ ---------- ----------- --------------- ----------
11SAL                                       9          2           1 NONE            .111111111
12ID                                    10000          0           1 NONE                 .0001
13
14LHR@orclasm > SELECT 1/9,1/10000 FROM DUAL; 
15
16       1/9    1/10000
17---------- ----------
18.111111111      .0001
     

在有直方圖的狀況下:

 1LHR@orclasm > EXEC DBMS_STATS.GATHER_TABLE_STATS(USER,'T_MD_20170606_LHR',CASCADE=>TRUE,METHOD_OPT=>'FOR COLUMNS SAL SIZE 9'); 
2
3PL/SQL procedure successfully completed.
4
5LHR@orclasm > SELECT D.COLUMN_NAME,D.NUM_DISTINCT,D.NUM_NULLS,D.NUM_BUCKETS,D.HISTOGRAM,D.DENSITY FROM DBA_TAB_COLUMNS D WHERE D.TABLE_NAME = 'T_MD_20170606_LHR';
6
7COLUMN_NAME                    NUM_DISTINCT  NUM_NULLS NUM_BUCKETS HISTOGRAM          DENSITY
8------------------------------ ------------ ---------- ----------- --------------- ----------
9SAL                                       9          2           9 FREQUENCY        .00005001
10ID                                    10000          0           1 NONE                 .0001
11
12LHR@orclasm > SELECT 1/(2*(10000-2)) FROM DUAL;
13
141/(2*(10000-2))
15---------------
16      .00005001
     

數據字典中的字段LOW_VALUEHIGH_VALUE分別存儲的就是目標列的最小值和最大值,CBOLOW_VALUEHIGH_VALUE來評估對目標列作範圍查詢時的可選擇率。不過這兩個字段的返回值是RAW類型的,須要轉換後才能識別。可使用UTL_RAW.CAST_TO_NUMBERUTL_RAW.CAST_TO_VARCHAR2等函數來轉換,也可使用存儲過程DBMS_STATS.CONVERT_RAW_VALUE來轉換,下面給出示例:

 1CREATE OR REPLACE FUNCTION FUN_DISPLAY_RAW_LHR(P_RAWVAL RAW,P_TYPE   VARCHAR2)
2  RETURN VARCHAR2 IS
3  V_NUMBER    NUMBER;
4  V_VARCHAR2  VARCHAR2(32);
5  V_DATE      DATE;
6  V_NVARCHAR2 NVARCHAR2(32);
7  V_ROWID     ROWID;
8  V_CHAR      CHAR(32);
9BEGIN
10  IF (P_TYPE = 'NUMBER' OR P_TYPE = 'FLOAT'THEN
11    DBMS_STATS.CONVERT_RAW_VALUE(P_RAWVAL, V_NUMBER);
12    RETURN TO_CHAR(V_NUMBER);
13  ELSIF (P_TYPE = 'VARCHAR2') THEN
14    DBMS_STATS.CONVERT_RAW_VALUE(P_RAWVAL, V_VARCHAR2);
15    RETURN TO_CHAR(V_VARCHAR2);
16  ELSIF (P_TYPE = 'DATE' OR P_TYPE LIKE 'TIMESTAMP%') THEN
17    DBMS_STATS.CONVERT_RAW_VALUE(P_RAWVAL, V_DATE);
18    RETURN TO_CHAR(V_DATE);
19  ELSIF (P_TYPE = 'NVARCHAR2') THEN
20    DBMS_STATS.CONVERT_RAW_VALUE(P_RAWVAL, V_NVARCHAR2);
21    RETURN TO_CHAR(V_NVARCHAR2);
22  ELSIF (P_TYPE = 'ROWID') THEN
23    DBMS_STATS.CONVERT_RAW_VALUE(P_RAWVAL, V_ROWID);
24    RETURN TO_CHAR(V_ROWID);
25  ELSIF (P_TYPE = 'CHAR') THEN
26    DBMS_STATS.CONVERT_RAW_VALUE(P_RAWVAL, V_CHAR);
27    RETURN TO_CHAR(V_CHAR);
28  ELSIF (P_TYPE = 'RAW') THEN
29    RETURN TO_CHAR(P_RAWVAL);
30  ELSE
31    RETURN 'UNKNOWN DATATYPE!';
32  END IF;
33EXCEPTION
34  WHEN OTHERS THEN
35    RETURN 'ERRORS!';
36END FUN_DISPLAY_RAW_LHR;
     

使用該函數查詢:

 1CREATE TABLE T_AA_20170606_LHR AS SELECT * FROM DBA_OBJECTS;
2EXEC DBMS_STATS.gather_table_stats(USER,'T_AA_20170606_LHR');
3SELECT D.COLUMN_NAME,
4       D.LOW_VALUE,
5       D.HIGH_VALUE,
6       D.DENSITY,
7       D.NUM_DISTINCT,
8       D.NUM_NULLS,
9       D.NUM_BUCKETS,
10       D.HISTOGRAM,
11       D.DATA_TYPE,
12       FUN_DISPLAY_RAW_LHR(D.LOW_VALUE, D.DATA_TYPE) LOW_VALUE1,
13       FUN_DISPLAY_RAW_LHR(D.HIGH_VALUE, D.DATA_TYPE) HIGH_VALUE1--,
14       --UTL_RAW.CAST_TO_NUMBER(D.LOW_VALUE) LOW_VALUE2,
15       --UTL_RAW.CAST_TO_NUMBER(D.HIGH_VALUE) HIGH_VALUE2,
16  FROM USER_TAB_COLS D
17 WHERE D.TABLE_NAME = 'T_AA_20170606_LHR';
     

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

& 說明:

有關轉換的更多內容能夠參考個人BLOGhttp://blog.itpub.net/26736162/viewspace-2140335/

(三)系通通計信息

系通通計信息主要包括目標數據庫服務器CPU的主頻、單塊讀的平均耗費時間、多塊讀的平均耗費時間和單次多塊讀所能讀取的數據塊的平均值等。收集系通通計信息的方法主要是使用系統存儲過程:

1EXEC DBMS_STATS.GATHER_SYSTEM_STATS('start');
2系統正常負載運行一段時間
3EXEC DBMS_STATS.GATHER_SYSTEM_STATS('
stop');
4

     

或:

1EXEC DBMS_STATS.GATHER_SYSTEM_STATS(GATHERING_MODE => 'INTERVAL',INTERVAL =>1);--INTERVAL爲間隔時長,單位爲分鐘
     

系通通計信息主要存儲在SYS.AUX_STATS$表中,也可使用DBMS_STATS.GET_SYSTEM_STATS獲取系通通計信息的內容,修改系通通計信息可使用DBMS_STATS.SET_SYSTEM_STATS,刪除系通通計信息可使用DBMS_STATS.DELETE_SYSTEM_STATS

在未引入系通通計信息以前,CBO所計算的成本值所有是基於I/O來計算的;在Oracle引入了系通通計信息以後,實際上就額外地引入了CPU成本計算模型(CPU Cost model),今後之後,CBO所計算的成本值就包括I/O CostCPU Cost這兩個部分。CBO在計算成本的時候就會分別對它們各自計算,並將算出來的I/O CostCPU Cost值的總和做爲目標SQL新的成本值。

Oracle 9i開始,Oracle經過一個隱含參數「_OPTIMIZER_COST_MODEL」來控制是否開啓CPU Cost model。該參數的默認值爲CHOOSE,意思是若是SYS.AUX_STATS$表裏有相關記錄,那麼表示開啓CPU Cost model,不然就仍是沿用之前的成本計算模型(即計算的成本所有是I/O Cost)。

 1SYS@orclasm > set pagesize 9999
2SYS@orclasm > set line 9999
3SYS@orclasm > col NAME format a40
4SYS@orclasm > col KSPPDESC format a50
5SYS@orclasm > col KSPPSTVL format a20
6SYS@orclasm > SELECT a.INDX,
7  2         a.KSPPINM NAME,
8  3         a.KSPPDESC,
9  4         b.KSPPSTVL 
10  5  FROM   x$ksppi  a,
11  6         x$ksppcv b
12  7  WHERE  a.INDX = b.INDX
13  8  and lower(a.KSPPINM) like  lower('%&parameter%');
14Enter value for parameter: _OPTIMIZER_COST_MODEL
15old   8: and lower(a.KSPPINM) like  lower('%&parameter%')
16new   8: and lower(a.KSPPINM) like  lower('%_OPTIMIZER_COST_MODEL%')
17
18      INDX NAME                                     KSPPDESC                                           KSPPSTVL
19---------- ---------------------------------------- -------------------------------------------------- --------------------
20      1917 _optimizer_cost_model                    optimizer cost model                               CHOOSE
21
22SYS@orclasm > SET LINESIZE 9999
23SYS@orclasm > COL PVAL1 FOR 999999999
24SYS@orclasm > COL PVAL2 FOR A30
25SYS@orclasm > COL SNAME FOR A15
26SYS@orclasm > SELECT * FROM SYS.AUX_STATS$;
27
28SNAME           PNAME                               PVAL1 PVAL2
29--------------- ------------------------------ ---------- ------------------------------
30SYSSTATS_INFO   STATUS                                    COMPLETED
31SYSSTATS_INFO   DSTART                                    06-02-2017 13:54
32SYSSTATS_INFO   DSTOP                                     06-02-2017 13:55
33SYSSTATS_INFO   FLAGS                                   0
34SYSSTATS_MAIN   CPUSPEEDNW                           1752
35SYSSTATS_MAIN   IOSEEKTIM                              10
36SYSSTATS_MAIN   IOTFRSPEED                           4096
37SYSSTATS_MAIN   SREADTIM                                4
38SYSSTATS_MAIN   MREADTIM
39SYSSTATS_MAIN   CPUSPEED                             2099
40SYSSTATS_MAIN   MBRC
41SYSSTATS_MAIN   MAXTHR
42SYSSTATS_MAIN   SLAVETHR
     

結果含義以下所示:

CPUSPEEDNW:非工做量統計模式下CPU主頻,即每秒能夠完成的機器指命數據,直接來自硬件。

IOSEEKTIMI/O尋址時間(毫秒),默認值爲10,直接來自硬件。

IOTFRSPEEDI/O傳輸速率(字節/毫秒),默認爲4096

SREADTIM:讀取單個數據塊的平均時間,單位是毫秒(ms)。

MREADTIM:讀取多個數據塊的平均時間,單位是毫秒(ms)。

CPUSPEED:工做量統計模式下CPU主頻,根據當前工做量評估出一個合理值。

MBRCOracle收集完統計信息後評估出的一次多塊讀能夠讀幾個數據塊(DB_FILE_MULTIBLOCK_READ_COUNT)。

MAXTHR:最大I/O吞吐量(字節/秒)。

SLAVETHR:單個並行進程的最大吞吐量(字節/秒)。

SYSSTATS_INFO:系通通計信息的狀態和收集時間。

SYSSTATS_MAIN:系通通計信息的結果集。

SYSSTATS_TEMP:只有當收集系通通計信息時纔可用。

如下是10053事件trace關於系統統計數據的部分內容:

1-----------------------------
2SYSTEM STATISTICS INFORMATION
3-----------------------------
4  Using NOWORKLOAD Stats
5  CPUSPEEDNW: 3097 millions instructions/sec (default is 100)
6  IOTFRSPEED: 4096 bytes per millisecond (default is 4096)
7  IOSEEKTIM: 16 milliseconds (default is 10)
8  MBRC: -1 blocks (default is 16)
     

(四)內部對象統計信息

數據字典基表SYS.TAB_STATS$中會存儲X$表的表對象統計信息。默認狀況下(包括默認的自動統計信息收集做業在內),Oracle不會對X$系列表收集內部對象統計信息,因此默認狀況下SYS.TAB_STATS$中沒有任何記錄。

須要注意的是,X$表雖然只是內存結構,不佔用數據庫的物理存儲空間,但X$系列表的內部對象統計信息實際上已經被Oracle存儲在了數據字典裏,這些統計信息是佔用了實際的物理存儲空間的,這意味着X$表的統計信息已經被持久化了,並不會隨着數據庫的起停而消失。因此,實際上並不須要隨着數據庫的起停而對X$表反覆收集內部對象統計信息,除非系統的負載發生了很大的變化,以前收集的內部對象統計信息已經再也不具有表明性。

即便相關的X$表沒有內部對象統計信息,Oracle也不會在訪問這些X$表時使用動態採樣。在明確診斷出系統已有的性能問題是由於X$表的內部對象統計信息不許引發的,這個時候就應該收集X$表的內部對象統計信息,其它情形就不要收集了。由於X$表實際上就是內存結構,因此在RAC環境下收集內部對象統計信息時須要在每一個節點都進行收集統計信息。


本文選自《Oracle程序員面試筆試寶典》,做者:小麥苗



watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=      

---------------優質麥課------------

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

詳細內容能夠添加麥老師微信或QQ私聊。


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


About Me:小麥苗      

 本文做者:小麥苗,只專一於數據庫的技術,更注重技術的運用

● 做者博客地址:http://blog.itpub.net/26736162/abstract/1/

 本系列題目來源於做者的學習筆記,部分整理自網絡,如有侵權或不當之處還請諒解

 版權全部,歡迎分享本文,轉載請保留出處

 QQ:646634621  QQ羣:618766405

 提供OCP、OCM和高可用部分最實用的技能培訓

● 題目解答如有不當之處,還望各位朋友批評指正,共同進步

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=DBA寶典

長按下圖識別二維碼或微信掃描下圖二維碼來關注小麥苗的微信公衆號:xiaomaimiaolhr,學習最實用的數據庫技術。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


本文分享自微信公衆號 - DB寶(lhrdba)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索