Uważam, że może to mieć coś wspólnego z indeksami istniejącymi w kolumnach, których używasz w OR
orzeczenie.
Testowałem używając następujących w 11gR2.
create table scott.test as
select level l,
decode(mod(level,2), 1, 1, 2) x,
decode(mod(level,2), 1, 2, 1) y,
dbms_random.value(1, 3) z from dual
connect by level < 1000;
/
begin
dbms_stats.gather_table_stats('scott', 'test');
end;
/
Następnie wyjaśniłem następujące zapytania w TOAD, (EXPLAIN PLAN FOR
)
select x, y, z from scott.test
where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
;
SELECT STATEMENT Optimizer Mode=ALL_ROWS 10 4
TABLE ACCESS FULL COS_DM.TEST 10 280 4
select /*+ USE_CONCAT */ x, y, z from scott.test
where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
;
SELECT STATEMENT Optimizer Mode=ALL_ROWS 10 4
TABLE ACCESS FULL COS_DM.TEST 10 280 4
select x, y, z from test where (floor(z) = 1 and x = 1)
union all
select x, y, z from test where (floor(z) = 2 and y = 1)
;
SELECT STATEMENT Optimizer Mode=ALL_ROWS 10 8
UNION-ALL
TABLE ACCESS FULL COS_DM.TEST 5 140 4
TABLE ACCESS FULL COS_DM.TEST 5 140 4
Wygląda więc na to, że podpowiedź nie działa. Następnie dodałem indeks do kolumn x i y:
create index test_x on test (x, y);
begin
dbms_stats.gather_table_stats('scott', 'test');
end;
/
Ponowne uruchamianie zapytań teraz:
select x, y, z from scott.test
where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
;
SELECT STATEMENT Optimizer Mode=ALL_ROWS 10 4
TABLE ACCESS FULL COS_DM.TEST 10 280 4
select /*+ USE_CONCAT */ x, y, z from scott.test
where (floor(z) = 1 and x = 1) or (floor(z) = 2 and y = 1)
;
SELECT STATEMENT Optimizer Mode=ALL_ROWS 10 8
CONCATENATION
TABLE ACCESS FULL COS_DM.TEST 5 140 4
TABLE ACCESS FULL COS_DM.TEST 5 140 4
select x, y, z from test where (floor(z) = 1 and x = 1)
union all
select x, y, z from test where (floor(z) = 2 and y = 1)
;
SELECT STATEMENT Optimizer Mode=ALL_ROWS 10 8
UNION-ALL
TABLE ACCESS FULL COS_DM.TEST 5 140 4
TABLE ACCESS FULL COS_DM.TEST 5 140 4
Wygląda na to, że po dodaniu indeksu (nawet jeśli nie jest używany ) optymalizator zdecydował się mimo wszystko skorzystać z podpowiedzi!
Może mógłbyś tego spróbować?