【发布时间】: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