2

I had the following problem with our Oracle 11 database and although there's a fix, I want to understand why its reacting this way.

We have two schemas: a "dev" schema which contains all the tables, views, plsql, ... and a "app" schema which contains synonyms to the dev-objects, i.e. statements don't contain schema names.

A dev-view references tables (select * from a a1 -> b -> a a2 union select * from c) in which there's a common column which is used for the selection, i.e. the selection predicate is pushed into table "a" (300k rows) and "b" (90k rows) selection via seperate index access, resulting in a very performant plan.

dev-fun is a deterministic, parallel function which simply does some string manipulation without further database access.

The selection on the view looks like: select * from view where common-column = fun(string) This works as expected on the dev schema, but if this is executed on the app schema, the plan becomes relatively very expensive, i.e. the result of fun(string) is not pushed down, but the tables are hash joined and the result is scanned for the element.

Still in the app schema, when I replace fun(string) with the function-result the plan becomes cheap again.

To solve the problem, I duplicated the view in the app schema instead of referencing it via a synonym, but in case of view/table-changes that means a potential source of defect, as we normally don't check the app schema ... The call to the function is still via the synonym and the view was duplicated as-is, i.e. it accesses the synonyms for the underlying tables ... and the plan is the same as if it was executed on the dev schema.

Apart of having selection grants on all underlying tables, I've also tried granting "query rewrite", "references" on the tables and "references" on the view. Furthermore I've tried the authid-options on the function. I have to admit, that I haven't yet checked for row-level security, but we are not using them.

What else can I check for?

The oracle version is 11.0.2.2. Opening a oracle-ticket would be only a theoretical option, as we don't have direct support access and the layer in-between is even more frustrating as living with the maintaining issue.

I know that typically a explain-plan would be helpful, but lets try it first without it, as I suspect the problem somewhere else.

Update (14.10.2013):

  • Hinting to use nested loops doesn't work.
  • function based index aren't used.

Indexed access: select * from v_vt_betreuer where vtid = 11803056;

enter image description here

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

enter image description here

Copied view: i.e. when the view is copied into the app schema

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

enter image description here

4

2 回答 2

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

于 2013-10-13T08:30:15.630 回答
0

您确定您没有使用架构 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;
于 2013-10-19T18:32:14.717 回答