微課sql最佳化(7)、統計資訊收集(5)-關於直方圖

orastar發表於2020-03-03

1、直方圖介紹


    你可以為列統計直方圖。這些直方圖為列資料的分佈情況提供準確的估算。當列資料傾斜時,直方圖提供更為最佳化的選擇性估算,為資料分佈不均勻的情況提供最優的執行計劃。
Oracle Database為提供2種類別的列統計資訊直方圖:
  • Height-Balanced Histograms
  • Frequency Histograms
    資料庫儲存直方圖資訊*TAB_COL_STATISTICS檢視(使用者和DBA)。列值範圍:HEIGHTBALANCED, FREQUENCY, or NONE。
2、Height-Balanced Histograms
    在height-balanced histogram中,列值被劃分為桶,使得每個桶包含大致相同數量的行。直方圖顯示端點在值範圍內的位置。
考慮一個my_col值為1到100之間的列,以及一個10個桶的直方圖。如果資料my_col均勻分佈,則直方圖看起來與圖13-1類似,其中數字是端點值。例如,第七個桶具有值在60到70之間的行。
圖13-1具有均勻分佈的高度平衡直方圖

    每個桶中的行數為總行數的10%。在這個均勻分佈的例子中,40%的行的值在60到100之間。
如果資料不均勻分佈,則直方圖可能如圖13-2所示。在這種情況下,大多數行的列的值為5。只有10%的行的值在60到100之間。
圖13-2具有非均勻分佈的高度平衡直方圖
    您可以使用USER_TAB_HISTOGRAMS表格檢視高度平衡的直方圖,如示例13-1所示。
  1. BEGIN
  2.   DBMS_STATS . GATHER_table_STATS  (  
  3.     OWNNAME  = >   'OE' ,  
  4.     TABNAME  = >   'INVENTORIES' ,  
  5.     METHOD_OPT  = >   'FOR COLUMNS SIZE 10 quantity_on_hand'   ) ;
  6. END ;
  7. /

  8. SELECT  COLUMN_NAME ,  NUM_DISTINCT ,  NUM_BUCKETS ,  HISTOGRAM 
  9. FROM  USER_TAB_COL_STATISTICS
  10. WHERE  TABLE_NAME  =   'INVENTORIES'   AND  COLUMN_NAME  =   'QUANTITY_ON_HAND' ;

  11. COLUMN_NAME NUM_DISTINCT NUM_BUCKETS HISTOGRAM
  12. ------------------------------ ------------ ----------- ---------------
  13. QUANTITY_ON_HAND 237 10 HEIGHT BALANCED

  14. SELECT  ENDPOINT_NUMBER ,  ENDPOINT_VALUE 
  15. FROM  USER_TAB_HISTOGRAMS
  16. WHERE  TABLE_NAME  =   'INVENTORIES'   AND  COLUMN_NAME  =   'QUANTITY_ON_HAND'
  17. ORDER   BY  ENDPOINT_NUMBER ;

  18. ENDPOINT_NUMBER ENDPOINT_VALUE
  19. --------------- --------------
  20.               0 0
  21.               1 27
  22.               2 42
  23.               3 57
  24.               4 74
  25.               5 98
  26.               6 123
  27.               7 149
  28.               8 175
  29.               9 202
  30.              10 353
       在示例13-1查詢輸出中,一行(1-10)對應於直方圖中的每個桶。Oracle資料庫向該直方圖新增了特殊的第0個資料桶,因為第1個資料桶(27)中的值不是quantity_on_hand列的最小值。第0個桶的最小值為0 quantity_on_hand。

3、 frequency histogra m


    在 frequency histogram中,列的每個值對應於直方圖的單個桶。每個桶包含此單個值的出現次數。例如,假設36行包含列的值1 warehouse_id。端點值1具有端點號36。
資料庫在以下條件下自動建立頻率直方圖,而不是高度平衡的直方圖:
  • 不同值的數量小於或等於指定的直方圖桶數(最多254個)。
  • 每個列值重複一次。
您可以使用USER_TAB_HISTOGRAMS檢視檢視頻率直方圖,如示例13-2所示。
  1. BEGIN
  2.   DBMS_STATS . GATHER_TABLE_STATS  (  
  3.     OWNNAME  = >   'OE' ,  
  4.     TABNAME  = >   'INVENTORIES' ,  
  5.     METHOD_OPT  = >   'FOR COLUMNS SIZE 20 warehouse_id'   ) ;
  6. END ;
  7. /

  8. SELECT  COLUMN_NAME ,  NUM_DISTINCT ,  NUM_BUCKETS ,  HISTOGRAM 
  9. FROM  USER_TAB_COL_STATISTICS
  10. WHERE  TABLE_NAME  =   'INVENTORIES'   AND  COLUMN_NAME  =   'WAREHOUSE_ID' ;

  11. COLUMN_NAME NUM_DISTINCT NUM_BUCKETS HISTOGRAM
  12. ------------------------------ ------------ ----------- ---------------
  13. WAREHOUSE_ID 9 9 FREQUENCY

  14. SELECT  ENDPOINT_NUMBER ,  ENDPOINT_VALUE 
  15. FROM  USER_TAB_HISTOGRAMS
  16. WHERE  TABLE_NAME  =   'INVENTORIES'   AND  COLUMN_NAME  =   'WAREHOUSE_ID'
  17. ORDER   BY  ENDPOINT_NUMBER ;

  18. ENDPOINT_NUMBER ENDPOINT_VALUE
  19. --------------- --------------
  20.              36 1
  21.             213 2
  22.             261 3
  23.             370 4
  24.             484 5
  25.             692 6
  26.             798 7
  27.             984 8
  28.            1112 9
在例13-2中,第一個桶為warehouse_id1。該值在表中顯示36次,如以下查詢所證實:
oe@PROD> SELECT COUNT(*) FROM inventories WHERE warehouse_id = 1;
 
  COUNT(*)
----------
        36

5、 練習4 、直方圖最佳化練習


統計已銷戶使用者數量,請最佳化以下語句
select count(1) from ht.c_cons where status='close';
  1. SQL >   select   status , count ( 1 )   from   ht . c_cons   group   by   status ;

  2. STATUS                              COUNT ( 1 )
  3. ------------------------------------------------------------ ----------
  4. close                                 19
  5. open                                 9519
  6. creating                             462

  7. SQL >   create   index  ht . idx_c_cons_status  on  ht . c_cons ( status ) ;
  8. SQL > col  owner  for  a10
  9.   col  table_name  for  a20
  10. col  column_name  for  a20
  11. col  data_type  for  a30
  12. col  histogram  for  a20
  13. select  owner , table_name , column_name , data_type ,
  14. column_id , num_distinct , histogram , NUM_NULLS , LAST_ANALYZED          from  
  15. dba_tab_columns  where  table_name = 'C_CONS'   and  owner = 'HT'
  16. order   by  column_id ; SQL >  SQL >  SQL >  SQL >  SQL >  2 3 4 

  17. OWNER              TABLE_NAME        COLUMN_NAME     DATA_TYPE             COLUMN_ID NUM_DISTINCT HISTOGRAM         NUM_NULLS LAST_ANALYZED
  18. ---------- -------------------- -------------------- ------------------------------ ---------- ------------ -------------------- ---------- ------------------------------
  19. HT              C_CONS        CONS_NO       NUMBER                  1          10000 NONE             0 20 - AUG - 17
  20. HT          C_CONS        CONS_NAME      VARCHAR2                  2          5057 NONE             0 20 - AUG - 17
  21. HT          C_CONS        ORG_NAME      VARCHAR2                  3             12 NONE             0 20 - AUG - 17
  22. HT          C_CONS        BUILD_DATE      DATE                  4          10000 NONE             0 20 - AUG - 17
  23. HT          C_CONS        STATUS          VARCHAR2                  5              3 NONE             0 20 - AUG - 17

  24. SQL >  exec DBMS_STATS . GATHER_TABLE_STATS ( ownname  = >   'HT' , tabname  = >   'C_CONS' , estimate_percent  = >  30 , method_opt  = >   'for columns size 50 status' , no_invalidate  = >   FALSE , degree  = >  4 , cascade   = >   TRUE ) ;
  25. PL / SQL procedure successfully completed .
  26. SQL >   col  owner  for  a10
  27. SQL >   col  table_name  for  a20
  28. col  column_name  for  a20
  29. col  data_type  for  a30
  30. col  histogram  for  a20
  31. select  owner , table_name , column_name , data_type ,
  32. column_id , num_distinct , histogram , NUM_NULLS , LAST_ANALYZED          from  
  33. dba_tab_columns  where  table_name = 'C_CONS'   and  owner = 'HT'
  34. order   by  column_id ; SQL >  SQL >  SQL >  SQL >  2 3 4 

  35. OWNER     TABLE_NAME        COLUMN_NAME     DATA_TYPE             COLUMN_ID NUM_DISTINCT HISTOGRAM         NUM_NULLS LAST_ANALYZED
  36. ---------- -------------------- -------------------- ------------------------------ ---------- ------------ -------------------- ---------- ------------------------------
  37. HT     C_CONS        CONS_NO       NUMBER                  1     10000 NONE             0 20 - AUG - 17
  38. HT     C_CONS        CONS_NAME      VARCHAR2                  2     5057 NONE             0 20 - AUG - 17
  39. HT     C_CONS        ORG_NAME      VARCHAR2                  3         12 NONE             0 20 - AUG - 17
  40. HT     C_CONS        BUILD_DATE      DATE                  4     10000 NONE             0 20 - AUG - 17
  41. HT     C_CONS        STATUS          VARCHAR2                  5         3 FREQUENCY             0 20 - AUG - 17
  42. SQL >   select   count ( 1 )   from  ht . c_cons  where  status = 'open' ;
  43. Execution Plan
  44. ----------------------------------------------------------
  45. Plan hash  value :  2016425671

  46. -------------------------------------------------------------------------------------------
  47. |  Id  |  Operation      |  Name          |   Rows   |  Bytes  |  Cost  ( % CPU ) |  Time      |
  48. -------------------------------------------------------------------------------------------
  49. |  0  |   SELECT  STATEMENT  |            |     1  |     6  |     8  ( 0 ) |  00 : 00 : 01  |
  50. |  1  |  SORT AGGREGATE  |            |     1  |     6  |       |       |
  51. | *  2  |   INDEX  FAST FULL SCAN |  IDX_C_CONS_STATUS  |  9639  |  57834  |     8  ( 0 ) |  00 : 00 : 01  |
  52. -------------------------------------------------------------------------------------------

  53. Predicate Information  ( identified   by  operation id ) :
  54. ---------------------------------------------------
  55.    2  -  filter ( "STATUS" = 'open' )
  56. Statistics
  57. ----------------------------------------------------------
  58.      1 recursive calls
  59.      0 db block gets
  60.      28 consistent gets
  61.      0 physical reads
  62.      0 redo  size
  63.     527 bytes sent via SQL * Net  to  client
  64.     523 bytes received via SQL * Net  from  client
  65.      2 SQL * Net roundtrips  to / from  client
  66.      0 sorts  ( memory )
  67.      0 sorts  ( disk )
  68.      1  rows  processed
  69. SQL >  
  70. SQL >   select   count ( 1 )   from  ht . c_cons  where  status = 'close' ;
  71. Execution Plan
  72. ----------------------------------------------------------

  73. Plan hash  value :  2292286995

  74. ---------------------------------------------------------------------------------------
  75. |  Id  |  Operation      |  Name      |   Rows   |  Bytes  |  Cost  ( % CPU ) |  Time  |
  76. ---------------------------------------------------------------------------------------
  77. |  0  |   SELECT  STATEMENT  |           |  1  |  6  |  1     ( 0 ) |  00 : 00 : 01  |
  78. |  1  |  SORT AGGREGATE  |           |  1  |  6  |        |       |
  79. | *  2  |   INDEX  RANGE SCAN |  IDX_C_CONS_STATUS  |  24  |  144  |  1     ( 0 ) |  00 : 00 : 01  |
  80. ---------------------------------------------------------------------------------------

  81. Predicate Information  ( identified   by  operation id ) :
  82. ---------------------------------------------------

  83.    2  -   access ( "STATUS" = 'close' )


  84. Statistics
  85. ----------------------------------------------------------
  86.      1 recursive calls
  87.      0 db block gets
  88.      2 consistent gets
  89.      0 physical reads
  90.      0 redo  size
  91.     526 bytes sent via SQL * Net  to  client
  92.     523 bytes received via SQL * Net  from  client
  93.      2 SQL * Net roundtrips  to / from  client
  94.      0 sorts  ( memory )
  95.      0 sorts  ( disk )
  96.      1  rows  processed

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31442014/viewspace-2678257/,如需轉載,請註明出處,否則將追究法律責任。

相關文章