2011-01-31 20 views
6

Mam tabeli, demo_fact w Oracle 11g i ma kilka kolumn wirtualnych zdefiniowane jako takie:Oracle zapytanie przepisać z wirtualnych kolumn w tabeli źródłowej

ALTER TABLE demo_fact ADD (demo_measure_from_virtual NUMBER GENERATED ALWAYS AS 
    (CASE WHEN demo_category_column = 20 THEN demo_numericdata_column ELSE 0 END) 
    VIRTUAL VISIBLE); 

to mam zmaterializował widok zdefiniowany jako

CREATE MATERIALIZED VIEW demo_agg_mv 
REFRESH FORCE ON DEMAND 
ENABLE QUERY REWRITE 
AS 
SELECT 
    demo_dim_one, 
    demo_dim_two, 
    SUM(demo_measure_from_virtual) demo_measure_from_virtual 
    FROM demo_fact 
    GROUP BY demo_dim_one, demo_dim_two 

teraz chcę Query Rewrite kopać w dniu następującym zapytaniem:

SELECT demo_dim_one, SUM(demo_measure_from_virtual) 
FROM demo_fact 
GROUP BY demo_dim_one 

ale tak nie jest. Pobiegłem EXPLAIN_REWRITE na i tu jest wyjście:

QSM-01150: query did not rewrite 
QSM-01102: materialized view, DEMO_AGG_MV, requires join back to table, 
      DEMO_FACT, on column, DEMO_MEASURE_FROM_VIRTUAL 
QSM-01082: Joining materialized view, DEMO_AGG_MV, with table, DEMO_FACT, 
      not possible 
QSM-01102: materialized view, DEMO_AGG_MV, requires join back to table, 
      DEMO_FACT, on column, DEMO_NUMERICDATA_COLUMN 

Historia: Robię to z 70m wierszy i 50 kolumn wirtualnych (wszystkie z nich mają taką samą strukturę, prostą instrukcję case powyżej, ale z innym kolumna porównania i inna kolumna wyników)

Ten problem pojawia się tylko wtedy, gdy tabela faktów zawiera wirtualne kolumny, ale zmiana ich na niewirtualną spowoduje zużycie zbyt dużej przestrzeni dyskowej. Dlaczego Oracle nie przepisuje zapytania ponownie? Co mogę zrobić, aby to naprawić?

Odpowiedz

2

Nie wiem, jak przydatne jest to dla ciebie, ale Oracle wymaga, aby wszystkie kolumny, do których został dołączony zgrupowany widok, zostały uwzględnione w oświadczeniu do przepisania. (edit przynajmniej w połączeniu z wirtualnymi kolumn. Jest to prawdopodobnie „nie z projektem” ...)

Jeśli spróbujesz explain_rewrite na

select 
    demo_dim_one, 
    sum(s) 
from (
    select 
     demo_dim_one, 
     sum(demo_measure_from_virtual) s 
    from 
     demo_fact 
    group by 
     demo_dim_one, 
     demo_dim_two 
) 
group by demo_dim_one 

powinien powiedzieć, że został przepisany pytanie.

Można to wykazać w taki sposób:

tabelę, w którym będzie określona kolumna wirtualna:

create table tq84_virt_col (
    a varchar2(2), 
    b varchar2(2), 
    c number, 
    d number 
); 


insert into tq84_virt_col values ('A', 'X', 1, 1); 
insert into tq84_virt_col values ('A', 'X', 2, 1); 
insert into tq84_virt_col values ('A', 'Y', 3, 0); 
insert into tq84_virt_col values ('A', 'Y', 4, 1); 

insert into tq84_virt_col values ('B', 'Y', 11, 1); 
insert into tq84_virt_col values ('B', 'X', 12, 0); 
insert into tq84_virt_col values ('B', 'X', 13, 1); 

Definicja kolumny wirtualną:

alter table tq84_virt_col add (
    virt_col number generated always as (
    case when d = 1 then c else 0 end 
) 
    virtual visible 
); 

zmaterializowany widok. Uwaga: Grupy go na kolumnach a i b:

create materialized view tq84_mat_view 
refresh force on demand 
enable query rewrite 
as 
select 
    a, b, 
    sum(virt_col) sum_virt_col 
from 
    tq84_virt_col 
group by 
    a,b 

Widok zmaterializowany nie zostaną wykorzystane, jak pan zauważył:

begin 
    dbms_mview.explain_rewrite(
    'select a, sum(virt_col) from tq84_virt_col group by a' 
); 
end; 
/

select message 
from rewrite_table; 

QSM-01150: query did not rewrite 
QSM-01102: materialized view, TQ84_MAT_VIEW, requires join back to table, TQ84_VIRT_COL, on column, VIRT_COL 
QSM-01082: Joining materialized view, TQ84_MAT_VIEW, with table, TQ84_VIRT_COL, not possible 
QSM-01102: materialized view, TQ84_MAT_VIEW, requires join back to table, TQ84_VIRT_COL, on column, C 

Teraz obie kolumny a i b są wybierane i grupowane (z zapytaniem zewnętrznym w celu zapewnienia tego samego zestawu wyników):

truncate table rewrite_table; 

begin 
    dbms_mview.explain_rewrite(
    'select a, sum(s) from (select a, sum(virt_col) s from tq84_virt_col group by a, b) group by a' 
); 
end; 
/

select message 
from rewrite_table; 

QSM-01151: query was rewritten 
QSM-01209: query rewritten with materialized view, TQ84_MAT_VIEW, using text match algorithm 
QSM-01219: no suitable materialized view found to rewrite this query 
+0

Świetne wyjaśnienie! Dzięki za poświęcenie czasu. Niefortunne dla mnie, że pracuję z SAP BusinessObjects, więc miałem nadzieję, że skorzystam z zapytania nie zagnieżdżonego. Zaznaczę to jako akceptowaną odpowiedź, aby wyjaśnić to tak dobrze i szybko. –