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;
Hashed access: select * from v_vt_betreuer where vtid = VTNRVOLL_TO_VTID(11803056);
Copied view: i.e. when the view is copied into the app schema
select * from v_vt_betreuer where vtid = VTNRVOLL_TO_VTID(11803056);