在Oracle 9中伪造存储概要(3)

发表于:2013-11-15来源:IT博客大学习作者:jametong点击数: 标签:oracle
3 1 INDEX(T1 T1_I1) 很不幸,我们还将注意到它现在包含3行如下形式的提示: 2 1 NOREWRITE 1 2 NOREWRITE 1 1 NOREWRITE 而原来我们只有两行: 2 1 NOREWRITE 1 1 NOREWRITE 我们引入

  3 1 INDEX(T1 T1_I1)

  很不幸,我们还将注意到它现在包含3行如下形式的提示:

  2 1 NOREWRITE

  1 2 NOREWRITE

  1 1 NOREWRITE

  而原来我们只有两行:

  2 1 NOREWRITE

  1 1 NOREWRITE

  我们引入了一个新的提示,也就是”Stage 1,Node 2″.我不敢说我确切的知道这是什么意思,但是它一定与这样一个事实有关,为了在另外一个Schema解析优化这个查询,Oracle执行了一个额外的步骤来将视图引用转换成基础表的引用.

  虽然目前这不会导致存储概要无法正确使用(或者如同它在这个简单的例子中这样),谁又能说Oracle在将来的版本又会有多挑剔呢.

  旧方法(2)

  因为视图引入了一个可能在将来版本变成错误的异常,我们不得不更加挑剔. 让我们试试下面的这种方法:

  Create a new schema.

  Create table T1 in that schema.

  Create ONLY the index T1_I1.

  Rebuild the outline in that schema

  如果比较存储概要重建前后user_outline_hints的详细内容(必须重新登录到原来的Schema来做这件事),我们将发现除了我们想要改变的那一行,它们是完全一样的.重新登录回原来的Schema,通过清空共享池以及打开存储概要做一个常规检查,我们将会发现修改后的存储概要已经被使用了.

  然而,还有一个潜在的威胁,不过这一次更加隐蔽.再回去看图-2中出现在Oracle 9中的新字段的定义-你认为字段user_table_name中保存的值将会是什么啊?它应该是有限制的表名称,例如:

  {User_name}.{table_name}

  在我们的例子中,这将告诉Oracle表T1实际上是一个属于新的Schema的表,而不是原来的Schema下面的表.即使Oracle确实在使用这个存储概要,这个表里的信息也充分说明Oracle是在错误的对象上面应用这个存储概要.

  另外,它现在现在有效,但是为什么有这个信息在这儿呢-可能是为了将来的版本增强做准备呢.

  可靠的赌注

  看来,要生成存储概要,而又不面临将来的风险就只有一种方法了,那就是尽可能的真实.

  在这个示例中,你需要删除主键索引,生成执行计划,然后替换掉主键.

  当然,你可能不想在生产环境做这件事,即使你在生产环境做了,存储概要也有可能选择走全表扫描(而不是走你想要的那个索引).

  底线是你必须至少在另一个数据库中有一个这个Schema的空闲拷贝,接着需要非常小心的操作这个拷贝以得到需要的存储概要.一旦得到这个存储概要,你就可以从一个数据库导出它并将其导入另外一个数据库.

  例如:在这个空闲的数据库上,删除主键以避免PK唯一扫描就是可行的.如果Oracle并没有自动的采用另外一个索引,你可以对系统说各种谎言,诸如:

  将optimizer_mode改成first_rows_1

  构造数据使得列N1上的数据是唯一的.(不过,不要将其改成唯一索引,这样生成出来的存储概要将是unique scan而不是range scan了).

  使用dbms_stats来使这个索引获得一个难以置信的clustering_factor.

  调整参数optimiser_index_caching来告诉系统,这个索引已经完全被缓存.

  调整optimiser_index_cost_adj来告诉系统,多块读要比单块读要慢100倍.

  使用dbms_stats修改aux_stats$表来达到上一条同样的宣称效果,并且添加这样一个事实,一次多块读的典型大小为2个块.

  重建这个索引以包含where从句中的所有字段.

  给定存储概要表中的内容,假使表的所有者不变,对象类型不变以及不改变索引的唯一度,几乎任何事情都可以做. 如果你可以构造一个数据集与环境来生成一份与生产系统没有内部不一致的存储概要,那么你就可以以任何方式来欺骗系统.

  结论

  相对于Oracle 8来讲,在Oracle 9中进入存储概要的信息变更更加精细了.之前可以非常容易也很明显无风险的”调整”存储概要的方法,现在还仍然可以工作,但是Oracle 9中收集的巨量的附加信息表明,之前的那种方法现在可能会给将来留下隐患.

  虽然Oracle 9中引入了一个编辑存储概要的包,但它当前还只是局限在交换表的连接顺序.除了使用第二套系统来调整索引(通过改变环境参数以及人造的统计信息)外, 看似不存在安全的干预存储概要的方法.

  参考文献

  Oracle 9i Release 2: Database Performance Tuning Guide and Reference - Chapter 7.

  Oracle 9I Release 2: Supplied PL/SQL Packages and Types Reference - Chapters 41 - 42

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