ITPub博客

首页 > 数据库 > Oracle > 直方图(histograms)

直方图(histograms)

原创 Oracle 作者:13811135929 时间:2017-02-28 14:02:19 0 删除 编辑
        直方图(histogram)本来是统计学概念,为什么数据库引入此概念,究其原因是因为通过直方图优化器可以生成较好的执行计划。
       一旦对列创建了直方图后,通过直方图可以看到列值各个数据出现的频率(注意这里说的是频率,并不一定是某数值出现的具体次数)。直方图分为两种类型:频度直方图以及高度平衡直方图。频度直方图针对列有少量的不同值比较有效,当列中不同值的数目较大,建议使用高度平衡直方图。Oracle会根据列中不同值的数量来自动判断所要创建的直方图类型。
      依然拿上篇博客的表为例子(http://blog.itpub.net/29827284/viewspace-2134398/)
  1. SQL> exec dbms_stats.gather_table_stats(USER,'T',method_opt=>'for columns skew size 11');
  2. SQL> select * from user_tab_histograms t where t.table_name='T' and COLUMN_NAME='SKEW';
  3. TABLE_NAME    COLUMN_NAME   ENDPOINT_NUMBER ENDPOINT_VALUE ENDPOINT_ACTUAL_VALUE
    ------------- ------------- --------------- -------------- ------------------------------
    T             SKEW                        1              1
    T             SKEW                        2              2
    T             SKEW                        3              3
    T             SKEW                        4              4
    T             SKEW                        5              5
    T             SKEW                        6              6
    T             SKEW                        7              7
    T             SKEW                        8              8
    T             SKEW                        9              9
    T             SKEW                       10             10
    T             SKEW                    10000          10000
      ENDPONIT_VALUE显示的是列值
      ENDPOINT_NUMBER显示的是累积的行数更严格的说是累积的频率。
     为了计算一个特定列值的频率要使用与它相关的endpoint_number值减去它之前的累计值。对于列SKEW中ENDPOINT_VALUE为10000,它对应的ENDPOINT_NUMBER=10000,上一个ENDPOINT_VALUE为10的ENDPOINT_NUMBER=10,那么说明ENDPOINT_VALUE为10000有10000-10=9990条记录。有了直方图,可以让优化器做出最优的执行计划。废话少说,通过实验说明:

点击(此处)折叠或打开

  1. SQL> explain plan for select * from t where skew=1;

  2. Explained.

  3. SQL> SELECT * FROM table(dbms_xplan.display);

  4. PLAN_TABLE_OUTPUT
  5. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  6. Plan hash value: 1601196873

  7. --------------------------------------------------------------------------
  8. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
  9. --------------------------------------------------------------------------
  10. | 0 | SELECT STATEMENT | | 1 | 7 | 7 (0)| 00:00:01 |
  11. |* 1 | TABLE ACCESS FULL| T | 1 | 7 | 7 (0)| 00:00:01 |
  12. --------------------------------------------------------------------------

  13. Predicate Information (identified by operation id):
  14. ---------------------------------------------------

  15.    1 - filter("SKEW"=1)


点击(此处)折叠或打开

  1. SQL> explain plan for select * from t where skew=10000;
  2. SQL> SELECT * FROM table(dbms_xplan.display);

  3. PLAN_TABLE_OUTPUT
  4. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  5. Plan hash value: 1601196873

  6. --------------------------------------------------------------------------
  7. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
  8. --------------------------------------------------------------------------
  9. | 0 | SELECT STATEMENT | | 9990 | 69930 | 7 (0)| 00:00:01 |
  10. |* 1 | TABLE ACCESS FULL| T | 9990 | 69930 | 7 (0)| 00:00:01 |
  11. --------------------------------------------------------------------------

  12. Predicate Information (identified by operation id):
  13. ---------------------------------------------------

  14.    1 - filter("SKEW"=10000)
可以看出收集信息创建了直方图后,评估出的基数相对准确了很多,从而避免生成错误的执行计划。为了更好的说明情况,可以在SKEW列建立索引

点击(此处)折叠或打开

  1. SQL> create index ind_skew on t(skew);

  2. Index created.

  3. SQL> explain plan for select * from t where skew=1;

  4. Explained.

  5. SQL> SELECT * FROM table(dbms_xplan.display);

  6. PLAN_TABLE_OUTPUT
  7. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  8. Plan hash value: 3288809695

  9. ----------------------------------------------------------------------------------------
  10. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
  11. ----------------------------------------------------------------------------------------
  12. | 0 | SELECT STATEMENT | | 1 | 7 | 2 (0)| 00:00:01 |
  13. | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 7 | 2 (0)| 00:00:01 |
  14. |* 2 | INDEX RANGE SCAN | IND_SKEW | 1 | | 1 (0)| 00:00:01 |
  15. ----------------------------------------------------------------------------------------

  16. Predicate Information (identified by operation id):
  17. ---------------------------------------------------

  18.    2 - access("SKEW"=1)

  19. 14 rows selected.

  20. SQL> explain plan for select * from t where skew=10000;

  21. Explained.

  22. SQL> SELECT * FROM table(dbms_xplan.display);

  23. PLAN_TABLE_OUTPUT
  24. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  25. Plan hash value: 1601196873

  26. --------------------------------------------------------------------------
  27. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
  28. --------------------------------------------------------------------------
  29. | 0 | SELECT STATEMENT | | 9990 | 69930 | 7 (0)| 00:00:01 |
  30. |* 1 | TABLE ACCESS FULL| T | 9990 | 69930 | 7 (0)| 00:00:01 |
  31. --------------------------------------------------------------------------

  32. Predicate Information (identified by operation id):
  33. ---------------------------------------------------

  34.    1 - filter("SKEW"=10000)
WHERE条件SKEW=1选择走索引,WHERE条件SKEW=10000因为返回条目占据了表的绝多部分记录,Oracle选择全表扫描,可以看出上面的两条语句根据实际情况生成了非常完美的执行计划。

  

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29827284/viewspace-2134417/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2014-08-25

  • 博文量
    28
  • 访问量
    70027