2011-01-31 3 views
6

У меня есть таблица, demo_fact в Oracle 11g, и она имеет несколько виртуальных столбцов, определенных в качестве таковых:Oracle переписывание запросов с виртуальными столбцов в исходной таблице

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); 

Тогда я материализованное представление определяется как

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 

Теперь я хочу Query Rewrite пнуть в на следующем запросе:

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

, но это не так. Я побежал EXPLAIN_REWRITE, и вот результат:

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 

Предыстория: Я делаю это с 70М строк и 50 виртуальных колонок (все они имеют ту же структуру, простое утверждение случая выше, но с другой столбец сравнения и другой столбец результатов)

Эта проблема, по-видимому, проявляется только в том случае, когда таблица фактов имеет виртуальные столбцы, но изменение их на не-виртуальное будет потреблять слишком много дискового пространства. Почему Oracle не переписывает запрос? Что я могу сделать, чтобы исправить это?

ответ

2

Я не знаю, насколько это полезно для вас, но для Oracle требуется, чтобы все столбцы, сгруппированные в виде материала, были включены в заявление, которое должно быть переписано. (редактировать по крайней мере, в сочетании с виртуальными столбцами. Это, вероятно, «не по дизайну» ...)

Если вы пытаетесь explain_rewrite на

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 

он должен вам сказать, что он переписан запрос.

Это может быть продемонстрирован следующим образом:

таблицы для, на котором будет определена виртуальная колонка:

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); 

Определение виртуальной колонки:

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

Материализованным Посмотреть. Примечание: это группы по колоннам a и 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 

Материализованных не будет использоваться вид, как вы заметили:

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 

Теперь оба колонок a и b выбраны и сгруппированы по (с внешним запросом для обеспечения того же набора результатов):

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

Отличное объяснение! Спасибо, что нашли время. Не повезло, что я работаю с SAP BusinessObjects, поэтому я надеялся использовать не-вложенный запрос. Я отмечу это как принятый ответ, чтобы объяснить это так хорошо и быстро. –