2016-09-19 12 views
0

以下のマテリアライズド・ビューおよびその基礎となるビューを使用して、いくつかのレポートを実現しています。マテリアライズド・ビューは、アプリケーションから完全に手動でリフレッシュされます(DBMS_SNAPSHOT.REFRESH( '"OVERALL_WEEKLY"、' C ');)。このコールの後、ビューはFRESH状態ですが、基になる表に対してDML操作が実行された後、マテリアライズド・ビューはNEEDS_COMPILE状態になります。 ビューのクエリは次のとおりです。 EBR_CYCLE_TIMEおよびEBR_AREAのテーブルの下落が頻繁に変化しています。したがってコミット時のリフレッシュは、私たちの目的のための選択肢ではありません。Oracle:基になるビューのデータ変更後にMWがNEEDS_COMPILE状態に無効化される理由

NEEDS_COMPILE状態を回避する手段はありますか? NEED_COMPILE状態の原因は何ですか?

CREATE OR REPLACE FORCE VIEW "OTD_WEEKLY" AS 
    SELECT 
    otd.WEEK, 
    otd.SITE_ID, 
    otd.AREA_ID, 
    otd.OTD_METRIC            AS CT_METRIC, 
    ROUND(100 * (SUM(otd.SUCCESS)/SUM(otd.CT_TOTAL_COUNT)), 2) AS OTD_VALUE 
    FROM 
    (SELECT 
     FC.MFL_FISCAL_YR_NUM * 100 + FC.MFL_FISCAL_WK_NUM AS WEEK, 
     r.BUSINESS_UNIT_ID        AS PAL2_ID, 
     a.site_id           AS SITE_ID, 
     a.area_def_id          AS AREA_ID, 
     a.PRIORITY          AS PRIORITY, 
     r.EBR_BUILD_SUBTYPE        AS NPI, 
     r.CORPORATE_TD         AS CTD, 
     ctd.NAME           AS OTD_METRIC, 
     COUNT(r.ebr_number)        AS CT_TOTAL_COUNT, 
     COUNT(
      CASE 
      WHEN (ct.TIME_ELAPSED) > (ct.TARGET * 86400) 
      THEN NULL 
      ELSE r.ebr_number 
      END)           AS SUCCESS, 
     COUNT(
      CASE 
      WHEN (ct.TIME_ELAPSED) > (ct.TARGET * 86400) 
      THEN r.ebr_number 
      ELSE NULL 
      END)           AS MISSED, 
     COUNT(DISTINCT r.ebr_number)      AS TOTAL_NUMBER_OF_EBR 
    FROM ebr_cycle_time ct 
     JOIN ebr_area a 
     ON (a.id = ct.ebr_area_id 
      AND ct.status = 'FINISHED' 
      AND a.ship_date IS NOT NULL) 
     JOIN ebr_request r 
     ON (a.ebr_id = r.id AND r.submit_date >= to_date((select STRING_VALUE from EBR_STATUS_TABLE where key = 'REPORT_DATE_FROM'),'DD.MM.YY')) 
     JOIN EBR_GROUP_CYCLE_TIME_DEF gctd 
     ON (ct.CYCLE_TIME_GROUP_DEF = gctd.ID) 
     JOIN EBR_CYCLE_TIME_DEF ctd 
     ON (ctd.ID = gctd.CYCLE_TIME_DEF_ID 
      AND ctd.OTD_METRIC = 'Y') 
     JOIN EBR_CYCLE_TIME_GROUP ctg 
     ON (ctg.id = gctd.CYCLE_TIME_GROUP_ID) 
     JOIN EEBR_MC_LCL_FISCAL FC 
     ON (FC.MFL_QUERY_DT = TRUNC(a.ship_date) AND fc.MFL_QUERY_DT > add_months(trunc(sysdate, 'MM'), -8) AND fc.MFL_QUERY_DT <= sysdate) 
    GROUP BY 
     r.BUSINESS_UNIT_ID, 
     a.site_id, 
     a.area_def_id, 
     ctd.name, 
     fc.mfl_fiscal_yr_num, 
     fc.mfl_fiscal_wk_num, 
     ct.target, 
     a.PRIORITY, 
     r.CORPORATE_TD, 
     r.EBR_BUILD_SUBTYPE 
    ) otd 
    GROUP BY 
    otd.WEEK, 
    otd.PAL2_ID, 
    otd.SITE_ID, 
    otd.AREA_ID, 
    otd.OTD_METRIC; 


CREATE OR REPLACE FORCE VIEW "LAGGING_SCORE_WEEKLY" AS 
    SELECT 
    dsc.SITE_ID, 
    dsc.AREA_ID, 
    dsc.CT_METRIC, 
    (dsc.ARCHIVE_YEAR * 100 + dsc.ARCHIVE_WEEK) AS WEEK, 
    ROUND(AVG(SCORE), 4)      AS SCORE 
    FROM 
    (SELECT 
     cts.site_id           AS SITE_ID, 
     ls.AREA_DEF_ID          AS AREA_ID, 
     ctd.name           AS CT_METRIC, 
     ctd.id            AS CT_ID, 
     fc.MFL_QUERY_DT          AS ARCHIVE_DAY, 
     fc.MFL_FISCAL_WK_NUM        AS ARCHIVE_WEEK, 
     fc.MFL_FISCAL_MTH_NUM        AS ARCHIVE_MONTH, 
     fc.MFL_FISCAL_YR_NUM        AS ARCHIVE_YEAR, 
     (fc.MFL_FISCAL_YR_NUM * 100 + fc.MFL_FISCAL_WK_NUM) AS WEEK, 
     CASE 
     WHEN SUM(cts.PENALTY) > 0 
     THEN SUM(cts.PENALTY) 
     ELSE 0 
     END             AS EBR_PENALTY, 
     COUNT(DISTINCT cts.ebr_number)      AS NUMBER_OF_EBR, 
     COUNT(DISTINCT (
     CASE 
     WHEN cts.LAGGING_TIME > 0 
      THEN cts.ebr_number 
     ELSE NULL 
     END))            AS NUMBER_OF_LAGGING_EBR, 
     CASE 
     WHEN SUM(cts.PENALTY) > 0 
     THEN greatest(100 - 100 * (SUM(cts.PENALTY)/COUNT(DISTINCT cts.ebr_number)), 0) 
     ELSE 100 
     END             AS SCORE 
    FROM EBR_CYCLE_TIME_SNAPSHOT cts 
     JOIN EBR_REQUEST r 
     ON (r.ebr_number = cts.ebr_number AND r.submit_date >= to_date((select STRING_VALUE from EBR_STATUS_TABLE where key = 'REPORT_DATE_FROM'),'DD.MM.YY')) 
     RIGHT JOIN EBR_LAGGING_STATISTIC ls 
     ON ((TRUNC(ls.stat_date) = TRUNC(cts.SNAPSHOT_TIME)) 
      AND ls.site_id = cts.site_id 
      AND cts.AREA_DEF_ID = ls.AREA_DEF_ID 
      AND ls.CT_DEF_ID = cts.CYCLE_TIME_DEF_ID) 
     JOIN EBR_CYCLE_TIME_DEF ctd 
     ON (ls.CT_DEF_ID = ctd.id 
      AND ctd.OTD_METRIC = 'Y') 
     JOIN EEBR_MC_LCL_FISCAL fc 
     ON (TRUNC(ls.STAT_DATE) = TRUNC(fc.MFL_QUERY_DT) AND fc.MFL_QUERY_DT > add_months(trunc(sysdate, 'MM'), -8)) 
    GROUP BY 
     cts.site_id, 
     ls.AREA_DEF_ID, 
     ctd.name, 
     ctd.id, 
     fc.MFL_QUERY_DT, 
     fc.MFL_FISCAL_WK_NUM, 
     fc.MFL_FISCAL_MTH_NUM, 
     fc.MFL_FISCAL_YR_NUM, 
     ls.NUMBER_OF_EBR, 
     ls.NUMBER_OF_LAGGING_EBR, 
     TRUNC(ls.STAT_DATE) 
    ) dsc 
    GROUP BY dsc.SITE_ID, 
    dsc.AREA_ID, 
    dsc.CT_METRIC, 
    dsc.ARCHIVE_WEEK, 
    dsc.ARCHIVE_MONTH, 
    dsc.ARCHIVE_YEAR; 


CREATE OR REPLACE FORCE VIEW "START_COMPLIANCE_WEEKLY" AS 
    SELECT 
    'Starts Compliance'          AS CT_METRIC, 
    a.site_id             AS SITE_ID, 
    a.area_def_id            AS AREA_ID, 
    ((lstw.MFL_FISCAL_YR_NUM * 100) + lstw.MFL_FISCAL_WK_NUM) AS WEEK, 
    ROUND(AVG(
       CASE 
       WHEN ((ct.START_DATE IS NOT NULL 
        AND TRUNC((ct.START_DATE AT TIME ZONE 'MST') AT TIME ZONE s.time_zone) > 
         TRUNC((a.FIRST_FIRM_START_DATE AT TIME ZONE 'MST') AT TIME ZONE s.time_zone)) 
        OR (ct.START_DATE IS NULL 
         AND next_day(TRUNC(sysdate) - 7, 'Sun') > 
          TRUNC((a.FIRST_FIRM_START_DATE AT TIME ZONE 'MST') AT TIME ZONE s.time_zone))) 
       THEN 0 
       ELSE 100 
       END), 2)          AS SCORE 
    FROM ebr_area a 
    JOIN ebr_request r 
     ON (a.ebr_id = r.id AND a.FIRST_FIRM_START_DATE IS NOT NULL 
      AND a.FIRST_FIRM_START_DATE <= next_day(TRUNC(sysdate) - 7, 'Sun') AND AND r.status <> 'CANCELLED' 
      AND r.submit_date >= to_date((select STRING_VALUE from EBR_STATUS_TABLE where key = 'REPORT_DATE_FROM'),'DD.MM.YY')) 
    JOIN ebr_site s 
     ON (s.id = a.site_id) 
    LEFT JOIN 
    (SELECT 
     ct.START_DATE AS START_DATE, 
     ct.ROUND  AS ROUND, 
     ct.ebr_area_id AS area_id 
    FROM ebr_cycle_time ct 
     JOIN EBR_GROUP_CYCLE_TIME_DEF gctd 
     ON (ct.CYCLE_TIME_GROUP_DEF = gctd.ID 
      AND ct.status <> 'NEW') 
     JOIN EBR_CYCLE_TIME_DEF ctd 
     ON (ctd.ID = gctd.CYCLE_TIME_DEF_ID 
      AND ctd.code = 'SITE_PROCESSING') 
    ) ct ON (ct.area_id = a.id) 
    JOIN EEBR_MC_LCL_FISCAL lstw 
     ON (lstw.MFL_QUERY_DT = TRUNC(FIRST_FIRM_START_DATE) AND lstw.MFL_QUERY_DT > add_months(trunc(sysdate, 'MM'), -8)) 
    GROUP BY 
    a.site_id, 
    s.time_zone, 
    a.area_def_id, 
    lstw.MFL_FISCAL_YR_NUM, 
    lstw.MFL_FISCAL_WK_NUM; 


CREATE MATERIALIZED VIEW "OVERALL_WEEKLY" 
    AS SELECT s.code AS SITE_CODE, 
    s.name  AS SITE_NAME, 
    reports.SITE_ID, 
    ad.NAME AS AREA, 
    ad.CODE AS AREA_CODE, 
    reports.AREA_ID, 
    reports.REPORT_TYPE, 
    reports.CT_METRIC, 
    reports.WEEK, 
    reports.SCORE 
FROM (
    (SELECT 'Starts Compliance' AS REPORT_TYPE, 
    AREA_ID, 
    SITE_ID, 
    CT_METRIC, 
    WEEK, 
    SCORE 
    FROM START_COMPLIANCE_WEEKLY 
) 
UNION 
    (SELECT 'OTD' AS REPORT_TYPE, 
    AREA_ID, 
    SITE_ID, 
    OTD_WEEKLY.CT_METRIC, 
    OTD_WEEKLY.WEEK, 
    OTD_WEEKLY.OTD_VALUE AS SCORE 
    FROM OTD_WEEKLY 
) 
UNION 
    (SELECT 'Lagging' AS REPORT_TYPE, 
    AREA_ID, 
    SITE_ID, 
    LAGGING_SCORE_WEEKLY.CT_METRIC, 
    LAGGING_SCORE_WEEKLY.WEEK, 
    LAGGING_SCORE_WEEKLY.SCORE 
    FROM LAGGING_SCORE_WEEKLY 
)) reports 
JOIN EBR_SITE s 
ON (s.id = reports.SITE_ID) 
JOIN EBR_AREA_DEF ad 
ON (ad.id = reports.area_id); 
+1

ただリラックスしてください。これは予想される動作です。 Oracle 10.1以降、私のMVでも同じことが分かりました。私は何年か前にこれについていくつかのメタルリンクがあるのを見ましたが、それを見つけることはできません。キーワード "MV"、 "NEED_COMPILE"でmetalinkで検索してみてください –

+0

あなたの経験を共有してくれてありがとう。私たちのDBA主張は、それが基になるテーブル/ビューのスキームによって引き起こされ、NEED_COMPILE状態は何らかのエラー状態です。しかし、あなたの経験とコメントは、それが基礎となるテーブル/ビューのDML操作によって引き起こされ、エラー状態ではないという私の意見を支持しています。 – RadekSohlich

答えて

2

これは予想される動作です。 NEEDS_COMPILEステータスは、MViewデータがソースデータと異なることを意味します。それは情報目的のためだけにある。​​が使用に適さない場合は、NEEDS_COMPILEステータスのMViewを無視できます。

参照MOSドキュメントID 264036.1:

のMVに関連する依存関係を自動的に 正しい動作を保証するために維持されています。 MVが作成されると、マテリアライズド・ビュー は、その定義で参照されるマスター表に依存します。 のDML 操作(INSERTまたはDELETE、UPDATEまたはDDL操作など)で、マテリアライズド・ビューに依存すると、 が無効になります。

関連する問題