【问题标题】:Synonyms causing an expensive plan导致昂贵计划的同义词
【发布时间】:2013-10-20 21:13:20
【问题描述】:

我的 Oracle 11 数据库存在以下问题,尽管有修复, 我想了解它为什么会有这样的反应。

我们有两个模式:一个“开发”模式,它包含所有的表、视图、plsql……和 一个“app”模式,其中包含开发对象的同义词,即语句不包含 架构名称。

开发视图引用表 (select * from a a1 -> b -> a a2 union select * from c) 其中有一个用于选择的公共列,即选择 谓词通过单独的选择被推入表“a”(300k 行)和“b”(90k 行)选择 索引访问,从而产生非常高效的计划。

dev-fun 是一个确定性的并行函数,它只是进行一些字符串操作 无需进一步的数据库访问。

视图上的选择看起来像:select * from view where common-column = fun(string) 这在开发模式上按预期工作,但如果在应用模式上执行, 该计划变得相对非常昂贵,即fun(string)的结果没有被推倒, 但是这些表是哈希连接的,并且会扫描结果中的元素。

仍然在应用程序架构中,当我将 fun(string) 替换为函数结果时,计划变为 又便宜了。

为了解决这个问题,我在应用架构中复制了视图,而不是通过 同义词,但在视图/表格更改的情况下,这意味着潜在的缺陷来源,因为我们 通常不检查应用程序架构... 对该函数的调用仍然是通过同义词进行的,并且视图按原样复制,即它 访问基础表的同义词......并且计划与执行时相同 在开发架构上。

除了在所有基础表上授予选择权限外,我还尝试在表上授予“查询重写”、“引用”和在视图上授予“引用”。此外,我已经尝试了该功能的 authid-options。我必须承认,我还没有检查过row-level security,但我们没有使用它们。

我还能检查什么?

oracle 版本为 11.0.2.2。打开 oracle-ticket 只是一个理论上的选择, 因为我们没有直接的支持访问权限,而且中间的层更令人沮丧 生活在维护问题上。

我知道通常解释计划会有所帮助,但如果没有它,让我们先尝试一下,因为 我怀疑是其他地方的问题。

更新(14.10.2013):

  • 提示使用嵌套循环不起作用。
  • 未使用基于函数的索引。

索引访问:select * from v_vt_betreuer where vtid = 11803056;

哈希访问:select * from v_vt_betreuer where vtid = VTNRVOLL_TO_VTID(11803056);

复制视图:即当视图被复制到应用架构中时

select * from v_vt_betreuer where vtid = VTNRVOLL_TO_VTID(11803056);

【问题讨论】:

  • 让我看看我是否理解:您有一个通过一个字段连接 2 个表的视图。您有此表的别名。你有一个确定性的功能。如果您通过函数在其自己的模式中的结果查询视图,则计划将获取索引,但如果您通过别名查询相同的视图,则不会。是吗?
  • 是的。联合的第一部分是表“a”(两次)与关联表“b”的单级分层连接。 join 属性不同于 common 属性(让我们称之为 vtid)。工会的另一张桌子很小。如果别名与文字一起使用,则再次使用索引。
  • 抱歉,最后一条评论有部分错误。公共属性用于连接 - 类似于ˋselect a1.vtid, a2.* from agent a1 join agency_employee b on (b.vtid = a1.vtid) join agent a2 on (a2.vtid = b.employee_vtid)ˋ
  • 您说 common 属性与 join 属性不同,并且您正在按 common 属性进行搜索,因此该属性仅在视图中出现一次。函数func(string)是用于变量/参数还是其他字段?
  • @Y.Ecarri 关于通用属性,我之前已经更正了该评论。该函数通过绑定参数使用,但当该函数与文字一起使用时也会发生同样的情况。我认为11g支持其他plsql使用的plsql函数inlin(e)ing,这是否也适用于sql?

标签: oracle oracle11g synonym sql-execution-plan


【解决方案1】:

尝试创建这样的索引:

CREATE INDEX func_index ON agency(fun(common_column))

这称为基于函数的索引。

我的猜测是这种类型的查询:

select a1.vtid, a2.* 
from agency a1 join agency_employee b on (b.vtid = a1.vtid)
join agency a2 on (a2.vtid = b.employee_vtid)

导致查询优化器这样做:

select a1.vtid, a2.* 
from agency a1 join agency_employee b on (func(b.vtid) = func(a1.vtid))
join agency a2 on (func(a2.vtid) = func(b.employee_vtid))

http://www.akadia.com/services/ora_function_based_index_2.html http://www.oracle-base.com/articles/8i/function-based-indexes.php

如果这种方法没有帮助,请检查您是否有 ROW LEVEL SECURITY:

http://docs.oracle.com/cd/E16655_01/server.121/e17609/tdpsg_ols.htm http://docs.oracle.com/cd/B19306_01/network.102/b14266/apdvcntx.htm#i1007410

【讨论】:

  • 我很好奇这是否会改变计划,因为连接中没有使用该功能......但当然优化器有时很神奇......我明天会提供更新当我回来工作时......
  • 抱歉,这种方法不起作用。在我添加了基于函数的索引之后(在 webcc_vertreter(VTNRVOLL_TO_VTID(vtid)) 上创建索引 abe_vertreter;在 webcc_vt_betreuer(VTNRVOLL_TO_VTID(vtid)) 上创建索引 abe_vertreter2;)......解释计划仍然保持不变。如果你好奇,我已经附上了问题中的计划。
  • 检查您是否具有行级安全性。在某些情况下,可以设置一个视图以使某些用户看不到整个表格。这可能会导致不同的执行计划。
  • 正如我的问题中提到的,我们不使用行级安全性。我刚刚再次与SELECT * FROM dba_policies 核对了这两个方案没有任何政策
【解决方案2】:

您确定您使用的不是架构 NPS_WEBCC 中的实际函数,而是架构 NPS_WEBCC_DEV 中的函数的同义词吗?

如果不允许 DEV 架构访问 APP 架构中的对象,则无法推送条件。 您必须将同义词的权限授予 DEV 模式,因为视图位于 DEV 模式中。这就是为什么当您将视图复制到 APP 架构时它开始工作的原因。

如果你在基于DEV函数的DEV模式中使用扩展统计,可能会出现另一个问题,但需要在权限问题之后进行梳理。

您可以通过检查以下查询的解释计划来验证它。他们应该给出优化的结果:

-- q1
-- "v_vt_betreuer" is a synonym in app schema to a view in dev schema 
select * from v_vt_betreuer where vtid = NPS_WEBCC_DEV.VTNRVOLL_TO_VTID(11803056);

-- q2
select * from NPS_WEBCC_DEV.v_vt_betreuer where vtid=NPS_WEBCC_DEV.VTNRVOLL_TO_VTID(11803056);

UPD 根据额外的调查,最有可能发生的问题是因为视图中缺少 MERGE 授权。必须为视图及其内部使用的所有子视图授予它。

GRANT MERGE VIEW ON v_vt_betreuer TO NPS_WEBCC;

【讨论】:

  • 我确定在 nps_webcc 中使用同义词来访问 nps_webcc_dev 中的函数。不确定是否可以授予同义词,但我会在星期一尝试。关于扩展统计,我认为我们不会在这些上使用直方图,但也会检查它。谢谢你对我的包容。
  • 两种选择都会导致昂贵的计划。关于扩展统计,我不想提供太多表格的内部信息(即屏幕截图),但是从上面的屏幕截图中可以看出,公共列(vtid)具有唯一索引扫描访问权限,但是有两个连接表中没有关于 vtid 的直方图。明天我会用直方图试一试...
  • 两种选择都会导致昂贵的计划这是我对第二季度的期望。在 DEV 架构下登录时可以查看 q2 执行计划吗?我认为这是一开始的,而且它肯定很便宜。如果 q2 在 DEV 下很便宜,在 APP 下很贵,那么它必须与赠款和政策有关。
  • q2 在 DEV 下很便宜。当前应用程序只有视图和基础表的选择权。在我的问题中也已经说过,我玩过“重写”和“参考”赠款,哪些赠款可能有帮助?
  • 我很确定你已经对函数执行了授权,否则它根本不会工作。您必须检查视图上的 MERGE 授权。这是允许您的应用程序架构在视图内推送条件的授权。 GRANT MERGE VIEW ON v_vt_betreuer TO NPS_WEBCC; 当然,“v_vt_betreuer”的所有内部视图都应允许这样做
猜你喜欢
  • 2016-01-31
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多