【过时的】STORED OUTLINE固化执行计划--私有和公有

ORACLE使用STORED OUTLINE固化执行计划--私有和公有

2014年01月03日 10:49:58 ezbit 阅读数:1686

版权声明:本文为博主原创文章,未经博主允许不得转载。个人技术网站:http://www.ezbit.ren https://blog.csdn.net/joeadai/article/details/17781293

利用存储纲要可以固定sql执行计划,存储纲要有一系列与sql语句相关的optimizer hints构成。当存储纲要可用是,oracle会自动根据这些hint生成对应sql语句的执行计划。存储纲要可以分为私有和公有,同时我们可以对存储纲要划分不同的类别(categories),并指定那一类存储纲要发挥作用,这无疑会方便dba的管理工作。存储纲要一旦存储,就不会随后续系统配置或者统计信息的变化而变化。(oracle 11g虽然支持存储纲要,但是oracle已经不建议使用存储纲要,而是使用SPM).

公有和私有

oracle可以创建公有的存储纲要,也可以创建私有的存储纲要。具有的语法格式如下:

创建公有存储纲要,相关信息会存放在outln用中,创建私有纲要时,相关信息会存放在当前用户模式下,因此当前用户需要具有DBMS_OUTLN_EDIT.CREATE_EDIT_TABLES的执行权限,以便创建相关对象(这不是必须的因为从10.1之后,会在system下创建临时表对象来存储私有的存储纲要)。

 
  1. SQL> show user

  2. USER 为 "OUTLN"

  3. SQL> l

  4. 1* select object_name,object_type from user_objects order by object_type

  5. SQL> /

  6.  
  7. OBJECT_NAME OBJECT_TYPE

  8. ------------------------------ -------------------

  9. OL$NAME INDEX

  10. OL$NODE_OL_NAME INDEX

  11. OL$SIGNATURE INDEX

  12. OL$HNT_NUM INDEX

  13. SYS_IL0000000451C00021$$ INDEX

  14. SYS_LOB0000000451C00021$$ LOB

  15. ORA$GRANT_SYS_SELECT PROCEDURE

  16. OL$HINTS TABLE

  17. OL$NODES TABLE

  18. OL$ TABLE

  19.  
  20. 已选择10行。

从这里可以看出,公共存储纲要信息主要存放在OL$,OL$HINTS,OL$NODES三张表中。

首先,我们来创建一个公共纲要,创建纲要需要具有CREATE ANY OUTLINE权限

 
  1. SQL> create public outline outline1 on select count(*) from t1 where object_id < 100;

  2. create public outline outline1 on select count(*) from t1 where object_id < 100

  3. *

  4. 第 1 行出现错误:

  5. ORA-18005: 此操作需要 CREATE ANY OUTLINE 权限

  6.  
  7.  
  8. SQL> create public outline outline1 on select count(*) from t1 where object_id < 100;

  9.  
  10. 大纲已创建。


要是存储纲要发挥作用,需要在system或者session级别设置use_stored_outlines参数

 
  1. SQL> set autotrace on explain

  2. SQL> select count(*) from t1 where object_id < 100;

  3.  
  4. COUNT(*)

  5. ----------

  6. 98

  7.  
  8.  
  9. 执行计划

  10. ----------------------------------------------------------

  11. Plan hash value: 3724264953

  12.  
  13. ---------------------------------------------------------------------------

  14. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

  15. ---------------------------------------------------------------------------

  16. | 0 | SELECT STATEMENT | | 1 | 13 | 295 (1)| 00:00:04 |

  17. | 1 | SORT AGGREGATE | | 1 | 13 | | |

  18. |* 2 | TABLE ACCESS FULL| T1 | 12 | 156 | 295 (1)| 00:00:04 |

  19. ---------------------------------------------------------------------------

  20.  
  21. Predicate Information (identified by operation id):

  22. ---------------------------------------------------

  23.  
  24. 2 - filter("OBJECT_ID"<100)

  25.  
  26. Note

  27. -----

  28. - dynamic sampling used for this statement (level=2)

  29.  
  30. SQL> create index i1 on t1(object_id);

  31.  
  32. 索引已创建。

  33.  
  34. SQL> select count(*) from t1 where object_id < 100;

  35.  
  36. COUNT(*)

  37. ----------

  38. 98

  39.  
  40.  
  41. 执行计划

  42. ----------------------------------------------------------

  43. Plan hash value: 3900446664

  44.  
  45. --------------------------------------------------------------------------

  46. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

  47. --------------------------------------------------------------------------

  48. | 0 | SELECT STATEMENT | | 1 | 13 | 2 (0)| 00:00:01 |

  49. | 1 | SORT AGGREGATE | | 1 | 13 | | |

  50. |* 2 | INDEX RANGE SCAN| I1 | 98 | 1274 | 2 (0)| 00:00:01 |

  51. --------------------------------------------------------------------------

  52.  
  53. Predicate Information (identified by operation id):

  54. ---------------------------------------------------

  55.  
  56. 2 - access("OBJECT_ID"<100)

  57.  
  58. Note

  59. -----

  60. - dynamic sampling used for this statement (level=2)

  61.  
  62. SQL> alter session set use_stored_outlines=true;

  63.  
  64. 会话已更改。

  65.  
  66. SQL> select count(*) from t1 where object_id < 100;

  67.  
  68. COUNT(*)

  69. ----------

  70. 98

  71.  
  72.  
  73. 执行计划

  74. ----------------------------------------------------------

  75. Plan hash value: 3724264953

  76.  
  77. ---------------------------------------------------------------------------

  78. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

  79. ---------------------------------------------------------------------------

  80. | 0 | SELECT STATEMENT | | 1 | 13 | 295 (1)| 00:00:04 |

  81. | 1 | SORT AGGREGATE | | 1 | 13 | | |

  82. |* 2 | TABLE ACCESS FULL| T1 | 4411 | 57343 | 295 (1)| 00:00:04 |

  83. ---------------------------------------------------------------------------

  84.  
  85. Predicate Information (identified by operation id):

  86. ---------------------------------------------------

  87.  
  88. 2 - filter("OBJECT_ID"<100)

  89.  
  90. Note

  91. -----

  92. -- outline "OUTLINE1" used for this statement

在system级别设置use_stored_outlines为true后,

 
  1. SQL> show user

  2. USER 为 "EASY2"

  3. SQL> select count(*) from t1 where object_id < 100;

  4.  
  5. COUNT(*)

  6. ----------

  7. 98

  8.  
  9.  
  10. 执行计划

  11. ----------------------------------------------------------

  12. Plan hash value: 3724264953

  13.  
  14. ---------------------------------------------------------------------------

  15. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

  16. ---------------------------------------------------------------------------

  17. | 0 | SELECT STATEMENT | | 1 | 13 | 295 (1)| 00:00:04 |

  18. | 1 | SORT AGGREGATE | | 1 | 13 | | |

  19. |* 2 | TABLE ACCESS FULL| T1 | 4411 | 57343 | 295 (1)| 00:00:04 |

  20. ---------------------------------------------------------------------------

  21.  
  22. Predicate Information (identified by operation id):

  23. ---------------------------------------------------

  24.  
  25. 2 - filter("OBJECT_ID"<100)

  26.  
  27. Note

  28. -----

  29. - outline "OUTLINE1" used for this statement


下面创建私有的存储纲要,创建私有纲要前可以执行如下语句来在当前模式下创建相关对象

 
  1. SQL> exec DBMS_OUTLN_EDIT.CREATE_EDIT_TABLES;

  2.  
  3. PL/SQL 过程已成功完成。

  4.  
  5. SQL> select * from tab;

  6.  
  7. TNAME TABTYPE CLUSTERID

  8. ------------------------------ ------- ----------

  9. OL$ TABLE

  10. OL$HINTS TABLE

  11. OL$NODES TABLE

  12. T1 TABLE

  13. SQL> select count(*) from OL$;

  14.  
  15. COUNT(*)

  16. ----------

  17. 0

 
  1. SQL> create private outline outline2 on select count(*) from t1 where object_id < 100;

  2.  
  3. 大纲已创建。

  4.  
  5. SQL> select count(*) from OL$;

  6.  
  7. COUNT(*)

  8. ----------

  9. 0

  10.  
  11. SQL> select count(*) from SYSTEM.OL$;

  12.  
  13. COUNT(*)

  14. ----------

  15. 1

  16.  

SESSION 1

 
  1. SQL> select count(*) from t1 where object_id < 100;

  2.  
  3. COUNT(*)

  4. ----------

  5. 98

  6.  
  7.  
  8. 执行计划

  9. ----------------------------------------------------------

  10. Plan hash value: 3900446664

  11.  
  12. --------------------------------------------------------------------------

  13. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

  14. --------------------------------------------------------------------------

  15. | 0 | SELECT STATEMENT | | 1 | 13 | 3 (0)| 00:00:01 |

  16. | 1 | SORT AGGREGATE | | 1 | 13 | | |

  17. |* 2 | INDEX RANGE SCAN| I1 | 4411 | 57343 | 3 (0)| 00:00:01 |

  18. --------------------------------------------------------------------------

  19.  
  20. Predicate Information (identified by operation id):

  21. ---------------------------------------------------

  22.  
  23. 2 - access("OBJECT_ID"<100)

  24.  
  25. Note

  26. -----

  27. - outline "OUTLINE2" used for this statement

SESSION 2:

 
  1. SQL> alter session set use_private_outlines=TRUE;

  2.  
  3. 会话已更改。

  4.  
  5. SQL> select count(*) from t1 where object_id < 100;

  6.  
  7. COUNT(*)

  8. ----------

  9. 98

  10.  
  11.  
  12. 执行计划

  13. ----------------------------------------------------------

  14. Plan hash value: 3900446664

  15.  
  16. --------------------------------------------------------------------------

  17. | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

  18. --------------------------------------------------------------------------

  19. | 0 | SELECT STATEMENT | | 1 | 13 | 2 (0)| 00:00:01 |

  20. | 1 | SORT AGGREGATE | | 1 | 13 | | |

  21. |* 2 | INDEX RANGE SCAN| I1 | 98 | 1274 | 2 (0)| 00:00:01 |

  22. --------------------------------------------------------------------------

  23.  
  24. Predicate Information (identified by operation id):

  25. ---------------------------------------------------

  26.  
  27. 2 - access("OBJECT_ID"<100)

  28.  
  29. Note

  30. -----

  31. - dynamic sampling used for this statement (level=2)

总结:oracle的存储纲要可以分为公有和私有,公有纲要的相关信息存放在OUTLN用户中,私有公有的相关信息存放在SYSTEM下的临时表中;由于私有纲要存放在临死表中,因此只能再当前session中使用,使用私有纲要需要设置USE_PRIVATE_OUTLINES(system或者session级别,主要这不是初始化参数),同样使用公有纲要需要设置USE_STORED_OUTLINES;

猜你喜欢

转载自blog.csdn.net/viviliving/article/details/91491044