在Oracle 9中伪造存储概要

发表于:2013-11-15来源:IT博客大学习作者:jametong点击数: 标签:oracle
本文与前一篇Oracle 8i/9i中的执行计划稳定性是Jonathan Lewis先生写的关于stored outline具体使用以及其中可能涉及到的风险系列文章,也是我所见到的关于stored outline介绍的最详细的文档了. 关于stored outline还有以下相关资料可以对照阅读下:

  译者注: 本文翻译自Jonathan Lewis的文章Faking Stored Outlines in Oracle 9, 可以从此处下载原文的word版本: Stored Outlines in Oracle 9.

  本文与前一篇Oracle 8i/9i中的执行计划稳定性是Jonathan Lewis先生写的关于stored outline具体使用以及其中可能涉及到的风险系列文章,也是我所见到的关于stored outline介绍的最详细的文档了. 关于stored outline还有以下相关资料可以对照阅读下:

  Oracle Outlines - aka Plan Stability By Kerry Osborne

  Plan stability in 10g - using existing cursors to create Stored Outlines and SQL profiles By Randolf Geist

  Stored Outlines and Plan Stability By Tim Hall

  Tuning Third-party Vendor Oracle Systems :Tuning when you can’t touch the code By Mark Ault

  原文为在Oracle 9中伪造存储概要

  在Oracle 9中伪造存储概要

  在前面的文章中,我讨论到存储概要,并且描述了一种通过滥用系统来生成你所需要存储概要的方法.我同时也指出,在Oracle 9中使用这种方法存在一些风险,因为存储在数据库中的细节信息已经变得非常复杂.在接下来的文章中,我将介绍一种合法的操作存储概要的方法,这种方法可以应用在Oracle 8与Oracle 9中.这篇文章的细节都是基于实验得出的,实验环境是Oracle 8.1.7.0与Oracle 9.2.0.1的默认安装环境.

  回顾

  当你知道如何通过给一段DML语句添加提示就可以让它运行的快很多,但是你却没有访问源代码并将提示放到适当位置的途径, 你会怎么做?

  在上一篇文章中,我展示了你可以如何用存储概要(也被称为执行计划稳定性)来驱使数据库引擎为你做这种工作.

  一个存储概要由两个组件组成(宽泛地讲)-一个你希望控制的SQL语句,一组每当Oracle发现这条SQL被优化都将在它上面应用的提示.这两个组件都被保存在一个被称为outln的数据库schema中.

  我们可以使用一组如图-1中类似的查询语句来检查保存在其中的SQL语句,以及附着在这条SQL语句上的提示.

  select name, used, sql_text

  from user_outlines

  where category = 'DEFAULT'

  ;

  select stage, node, hint

  from user_outline_hints

  where name = '{one of the names}'

  ;

  Figure 1 Examining stored outlines.

  在前面的文章中,我介绍了这样一种想法来欺骗系统, 使用合法的方法创建一个存储概要, 接着,使用一个文本相似的但已经添加过提示的语句来创建一个存储概要,最后,使用一组SQL语句来交换这两个存储概要的实际结果来修复存储概要.

  当时,我曾提到这种方法对Oracle 8来讲或许是安全的,但是由于在新版本中引入的变化, 在Oracle 9中可能会导致问题.

  这篇文章将对这些变化进行考查, 介绍一种合法的方法来得到你想要的一组存储到outln中的提示,用来解决你的那些问题语句.

  相关变化

  如果你登录到outln schema(在Oracle 9中它默认是锁住的)查看可用的表清单,你将发现Oracle 9比Oracle 8多出来一张表. 这些表为:

ol$ SQL语句
ol$hints 提示表
ol$nodes 查询块

  第三张表是一张新表,被用来将提示列表与这条SQL语句(一份内部重写的版本)的多个不同查询块.你还将发现,提示列表(ol$hints)也被加强了,其中还包括文本长度与偏移量的细节信息.

  图2为这三张表的详细描述,用星号标注了Oracle 9中出现的新字段.

  ol$

  OL_NAME VARCHAR2(30)

  SQL_TEXT LONG

  TEXTLEN NUMBER

  SIGNATURE RAW(16)

  HASH_VALUE NUMBER

  HASH_VALUE2 NUMBER ***

  CATEGORY VARCHAR2(30)

  VERSION VARCHAR2(64)

  CREATOR VARCHAR2(30)

  TIMESTAMP DATE

  FLAGS NUMBER

  HINTCOUNT NUMBER

  SPARE1 NUMBER ***

  SPARE2 VARCHAR2(1000) ***

  Ol$hints

  OL_NAME VARCHAR2(30)

  HINT# NUMBER

  CATEGORY VARCHAR2(30)

  HINT_TYPE NUMBER

  HINT_TEXT VARCHAR2(512)

  STAGE# NUMBER

  NODE# NUMBER

  TABLE_NAME VARCHAR2(30)

  TABLE_TIN NUMBER

  TABLE_POS NUMBER

  REF_ID NUMBER ***

  USER_TABLE_NAME VARCHAR2(64) ***

  COST FLOAT(126) ***

  CARDINALITY FLOAT(126) ***

  BYTES FLOAT(126) ***

  HINT_TEXTOFF NUMBER ***

  HINT_TEXTLEN NUMBER ***

  JOIN_PRED VARCHAR2(2000) ***

  SPARE1 NUMBER ***

  SPARE2 NUMBER ***

  ol$nodes (completely new in 9)

  OL_NAME VARCHAR2(30)

  CATEGORY VARCHAR2(30)

  NODE_ID NUMBER

  PARENT_ID NUMBER

  NODE_TYPE NUMBER

  NODE_TEXTLEN NUMBER

  NODE_TEXTOFF NUMBER

  Figure 2 The outln tables.

  你可能很快会注意到多处细节-有大量信息被基于这些表的视图排除在外了.视图user_outline_hints的视图定义完全没有改变,尽管表ol$hints上新增加了10个字段.实际上,这个视图在Oracle 8的时候就极度不足,因为它遗漏了相当有用的hint#字段.

  你还会注意到,Oracle 9现在有两个hash_value字段.如果你在Oracle 8与Oracle 9中对同样的SQL语句创建存储概要,你将发现它们拥有同样的hash_value,但是Oracle 9中对应的hash_value可能完全不同.

原文转自:http://blogread.cn/it/article/1030