Материализованное представление путем объединения представления и таблиц - PullRequest
0 голосов
/ 06 августа 2020

Можно ли создать материализованное представление, присоединившись к уже существующему представлению (обычно) ?. Мое требование - создать MVIEW для таблиц (A, B) и View (c). Является ли это возможным? Если да, наблюдались ли у нас проблемы с производительностью или проблема с кодом refre sh. Это нужно сделать на Oracle DB.

CREATE MATERIALIZED VIEW EMP_MVIEW refresh force ON COMMIT
select 
EMP.ID, EMP.NAME, DV.*
EMP_TABLE EMP
LEFT OUTER JOIN DETAILS_VIEW dv ON DV.EMP_ID=EMP.EMP_ID

1 Ответ

1 голос
/ 07 августа 2020

Перво-наперво. К сожалению, синтаксис соединения ANSI не разрешен для Oracle материализованного представления, используйте старый синтаксис соединения Oracle. Это ошибка в Oracle, я так полагаю

Все, что я собираюсь продемонстрировать своим ответом, касается только Материализованного с опцией FAST REFRESH

Возвращение к ваш исходный вопрос, можем ли мы использовать нормальное представление внутри материализованного представления с возможностью инкрементального refre sh:

Ответ: Нет

Сказав что, если мы попытаемся закончить с ошибкой и не сможем ее создать, как я продемонстрирую ниже,

Структура таблицы: (используется только для демонстрации в качестве примера, а не для фактических нормализованных таблиц

CREATE TABLE emp(emp_id NUMBER primary key
                ,empname VARCHAR2(1000));
CREATE TABLE address_details(address_id NUMBER primary key
                            ,address_text VARCHAR2(1000)
                            ,emp_id NUMBER);
CREATE TABLE salary_details(sal_id NUMBER primary key
                           ,salary NUMBER
                           ,emp_id NUMBER);

Материализованное представление Журналы:

--drop statements
DROP MATERIALIZED VIEW LOG ON emp;
DROP MATERIALIZED VIEW LOG ON address_details;
DROP MATERIALIZED VIEW LOG ON salary_details;

--create statements

--default
CREATE MATERIALIZED VIEW LOG ON emp;
CREATE MATERIALIZED VIEW LOG ON address_details;
CREATE MATERIALIZED VIEW LOG ON salary_details;

--with primary key (same as default above but I would stick to mention it explicitly for understanding and versioning (svn or git) purpose
CREATE MATERIALIZED VIEW LOG ON emp WITH PRIMARY KEY;
CREATE MATERIALIZED VIEW LOG ON address_details WITH PRIMARY KEY;
CREATE MATERIALIZED VIEW LOG ON salary_details WITH PRIMARY KEY;

--with primary key and rowid
CREATE MATERIALIZED VIEW log ON emp WITH PRIMARY KEY, ROWID;
CREATE MATERIALIZED VIEW log ON address_details WITH PRIMARY KEY, ROWID;
CREATE MATERIALIZED VIEW log ON salary_details WITH PRIMARY KEY, ROWID;

1. Сначала попробуйте создать MV с обычным представлением, как вы хотите:

CREATE OR REPLACE VIEW DETAILS_VIEW AS
SELECT sal_id
      ,salary
      ,address_id
      ,address_text
      ,sl.emp_id
      --,sl.rowid sl_rowid
      --,ad.rowid ad_rowid
FROM   salary_details sl
      ,address_details ad
WHERE  sl.emp_id = ad.emp_id;

DROP MATERIALIZED VIEW emp_mview;

CREATE MATERIALIZED VIEW EMP_MVIEW 
REFRESH FORCE ON COMMIT 
AS
SELECT emp.emp_id
      ,emp.empname
      ,dv.sal_id
      ,dv.salary
      ,dv.address_id
      ,dv.address_text
      --,emp.rowid emp_rowid
      --,dv.sl_rowid
      --,dv.ad_rowid
FROM   emp           emp
      ,details_view  dv
WHERE  emp.emp_id = dv.emp_id(+);

Результат:

ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view

Поверьте, я пробовал со всеми сценариями ios создание журнала с первичным ключом и rowid и добавление rowid в предложение select, и ничего не работает

Двигаясь вперед:

2. Вторая попытка создания MV со стандартными соединениями из oracle, поместив все отдельные базовые таблицы в предложение from:

Я создал журналы материализованного представления с первичным ключом опции, как я упоминал в Материализованное представление Журналы раздел выше.

CREATE MATERIALIZED VIEW EMP_MVIEW 
REFRESH FORCE ON COMMIT 
AS
SELECT emp.emp_id
      ,emp.empname
      ,sl.sal_id
      ,sl.salary
      ,ad.address_id
      ,ad.address_text
FROM   emp             emp
      ,salary_details  sl
      ,address_details ad
WHERE  emp.emp_id = sl.emp_id(+)
AND    emp.emp_id = ad.emp_id(+);

BIN GO: Materialized view created, но, подождите, подождите ... Значит, теперь я могу сделать FAST REFRESH? Давайте проверим:

Мы можем анализировать возможности материализованного представления, используя DBMS_MVIEW.EXPLAIN_MVIEW, который будет вставлять детали возможностей в таблицу с именем MV_CAPABILITIES_TABLE ( доступно с @ $ ORACLE_HOME / rdbms / admin / utlxmv. sql). Если у нас нет скрипта и грантов от DBA, вам необходимо его получить. Тем не менее, я все равно приведу нижеприведенные скрипты

КАК АНАЛИЗИРОВАТЬ ВОЗМОЖНОСТИ MV:

    --table structure
    CREATE TABLE mv_capabilities_table (
        statement_id      VARCHAR2(30),
        mvowner           VARCHAR2(30),
        mvname            VARCHAR2(30),
        capability_name   VARCHAR2(30),
        possible          CHAR(1),
        related_text      VARCHAR2(2000),
        related_num       NUMBER,
        msgno             INTEGER,
        msgtxt            VARCHAR2(2000),
        seq               NUMBER
    );
    
    --delete always before analyzing for a view to have only rows for a specific and not to have where clause to filter :)
    DELETE FROM mv_capabilities_table;
    
    --run this script which will analyze and insert into mv_capabilities_table
    BEGIN
       dbms_mview.explain_mview('EMP_MVIEW');
    END;
    /

/***ANALYSIS RESULT:***/

    --I am intersted only with data related to FAST REFRESH category
    SELECT capability_name
         ,possible
         ,substr(msgtxt
                ,1
                ,60) AS msgtxt
    FROM   mv_capabilities_table
    WHERE  capability_name LIKE '%FAST%';
    
    /**
    CAPABILITY_NAME                    POSSIBLE    MSGTXT
    REFRESH_FAST                            N 
    REFRESH_FAST_AFTER_INSERT               N      the SELECT list does not have the rowids of all the detail t
    REFRESH_FAST_AFTER_INSERT               N      mv log must have ROWID
    REFRESH_FAST_AFTER_INSERT               N      mv log must have ROWID
    REFRESH_FAST_AFTER_INSERT               N      mv log must have ROWID
    REFRESH_FAST_AFTER_ONETAB_DML           N      see the reason why REFRESH_FAST_AFTER_INSERT is disabled
    REFRESH_FAST_AFTER_ANY_DML              N      see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
    REFRESH_FAST_PCT                        N      PCT FAST REFRESH is not possible if query contains LEFT OUTE
    **/

Если вы посмотрите на результат с текстом **mv log must have ROWID** Приведенный выше результат анализа говорит нам, что в материализованных журналах просмотра отсутствует опция ROWID, и поэтому FAST REFRESH невозможно.

Примечание. В других столбцах в mv_capabilities_table также будет указано точные таблицы, которые я не включил, и вы можете проверить и протестировать их самостоятельно.

Двигаясь вперед ..

3. Третья попытка создания MV со стандартными объединениями из oracle и журналов MV с включенным параметром ROWID:

шаги: (не будет снова предоставлять сценарии, а просто предоставит шаги для моделирования

  • Я отбрасываю и заново создаю журналы MV с опцией ROWID, как указано в разделе Материализованные журналы просмотра выше.
  • Затем я отбрасываю и заново создаю то же определение MV, которое я использовал во второй попытке, которое в конечном итоге будет создано
  • Затем я попытаюсь повторить шаги для анализа MV, как описано в разделе КАК АНАЛИЗИРОВАТЬ ВОЗМОЖНОСТИ MV

Что я вижу в своем отчете об анализе:

/**
CAPABILITY_NAME                         POSSIBLE  MSGTXT
REFRESH_FAST                            N 
REFRESH_FAST_AFTER_INSERT               N         the SELECT list does not have the rowids of all the detail t
REFRESH_FAST_AFTER_ONETAB_DML           N         see the reason why REFRESH_FAST_AFTER_INSERT is disabled
REFRESH_FAST_AFTER_ANY_DML              N         see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
REFRESH_FAST_PCT                        N         PCT FAST REFRESH is not possible if query contains LEFT OUTE
**/

Уффффф: Я действительно устал, и снова у MV еще нет возможности FAST REFRESH, и причина подсказывает нам "the SELECT list does not have the rowids of all the detail tables"

Что это означает: следующий критерий для FAST REFRESH: Rowids of all the tables in the FROM list must appear in the SELECT list of the query

Итак,

4. Четвертая и последняя попытка создание MV со стандартными соединениями из oracle и журналов MV с опцией ROWID, включая d также идентификаторы строк таблиц сведений теперь включены в предложение select:

шаги:

  • Как и в случае с третьей попыткой, журналы MV, необходимые для первого обращения sh на месте, я отброшу и заново создам MV, но на этот раз с добавлением идентификаторов строк таблицы деталей.

Окончательный сценарий MV:

CREATE MATERIALIZED VIEW EMP_MVIEW 
REFRESH FORCE ON COMMIT 
AS
SELECT emp.emp_id
      ,emp.empname
      ,sl.sal_id
      ,sl.salary
      ,ad.address_id
      ,ad.address_text
      ,emp.rowid emp_rowid
      ,sl.rowid sl_rowid
      ,ad.rowid ad_rowid
FROM   emp             emp
      ,salary_details  sl
      ,address_details ad
WHERE  emp.emp_id = sl.emp_id(+)
AND    emp.emp_id = ad.emp_id(+);

Теперь как MV создан, давайте еще раз проанализируем возможности MV, как описано в разделе КАК АНАЛИЗИРОВАТЬ ВОЗМОЖНОСТИ MV . (скрещенные пальцы)

Результат:

SELECT capability_name
      ,possible
      ,substr(msgtxt,1,60) AS msgtxt
FROM   mv_capabilities_table
WHERE  capability_name LIKE '%FAST%';

/**
CAPABILITY_NAME                         POSSIBLE  MSGTXT
REFRESH_FAST                            Y 
REFRESH_FAST_AFTER_INSERT               Y 
REFRESH_FAST_AFTER_ONETAB_DML           Y 
REFRESH_FAST_AFTER_ANY_DML              Y 
REFRESH_FAST_PCT                        N         PCT FAST REFRESH is not possible if query contains LEFT OUTE
**/

Наконец, возможность REFRESH_FAST возможна, как мы видим POSSIBLE -> Y

Извините за длинный ответ, но я подумал, что должен рассказать, как я узнал о вещах, о которых было в прошлом MV, которыми можно было бы поделиться.

Некоторые ссылки, которые я всегда считал полезными в отношении Oracle материализованного представления :

Ура !!

...