Query rewrite without a group by

The actual query is more complicated involving 6 table joins. I have tried to re-produce the issue using a simple example shown below.
The "contacts" table has about 14 columns including the ones shown below.
All the table statistics are up to date.
select * from contacts;
customer_num          media_type          phone_area_code          phone_number
12345               FAXW               322               987-7865
12345               PHH               564               984-9872
12345               PHH               NULL               NULL
12345               PHW               873               922-9291
12345               PHW               762               872-9291
87272               PHH               456               982-9388
87272               FAXW               728               918-9281
76288               PHW               872               982-2882
The criteria is a customer can have more than 1 work or home phone.
work phone is identified as media_type = "PHW".
home phone is identified as media_type = "PHH".The example query is:
SELECT customer_num,
       <col-1>
       <col-10>,  
        MAX(decode(media_type,
                           'PHH',
                           phone_area_code || '''' || phone_number,
                           NULL)) home_phone,
       MAX(decode(media_type,
                           'PHW',
                           phone_area_code || '''' || phone_number,
                           NULL)) work_phone
FROM
   contacts
GROUP BY
      customer_num
      <col-1>,
      <col-10>;The explain plan is good. all indexes are used and the cost is less. The CPU Wait time is high.
How can this query be re-written without a GROUP BY?.For 2000 customers I am grouping 2000*11 records.
This is taking time.
I cannot post the explain plan or tkprof as I am not at work at present.
Can this query be re-written without using MAX(DECODE and GROUP BY?
Thanks in advance!

user1980 wrote:
How can this query be re-written without a GROUP BY?.For 2000 customers I am grouping 2000*11 records.
This is taking time.You could self-join the table, using a full outer join between the home phone records and the work phone records. I'm not convinced that it would be much faster than the aggregation, and might even be slower, but a nested loop join between the data sets would probably bring back the first rows faster than your current method.
The most efficient self join would probably come from partitioning the records based on the media type so that PHH and PHW records were in their own partitions. A hash join between the two sets would then be cheap. However, it might be worth looking at loading the table into a hash cluster (on customer_num) or using an index-organised table (on customer_num and media_type), either of which might improve join speed and also be more sympathetic to better performance in the rest of your application when you (presumably) want to retrieve all records for a particular customer_num.

Similar Messages

  • How to write a SQL Query without using group by clause

    Hi,
    Can anyone help me to find out if there is a approach to build a SQL Query without using group by clause.
    Please site an example if is it so,
    Regards

    I hope this example could illuminate danepc on is problem.
    CREATE or replace TYPE MY_ARRAY AS TABLE OF INTEGER
    CREATE OR REPLACE FUNCTION GET_ARR return my_array
    as
         arr my_array;
    begin
         arr := my_array();
         for i in 1..10 loop
              arr.extend;
              arr(i) := i mod 7;
         end loop;
         return arr;
    end;
    select column_value
    from table(get_arr)
    order by column_value;
    select column_value,count(*) occurences
    from table(get_arr)
    group by column_value
    order by column_value;And the output should be something like this:
    SQL> CREATE or replace TYPE MY_ARRAY AS TABLE OF INTEGER
      2  /
    Tipo creato.
    SQL>
    SQL> CREATE OR REPLACE FUNCTION GET_ARR return my_array
      2  as
      3   arr my_array;
      4  begin
      5   arr := my_array();
      6   for i in 1..10 loop
      7    arr.extend;
      8    arr(i) := i mod 7;
      9   end loop;
    10   return arr;
    11  end;
    12  /
    Funzione creata.
    SQL>
    SQL>
    SQL> select column_value
      2  from table(get_arr)
      3  order by column_value;
    COLUMN_VALUE
               0
               1
               1
               2
               2
               3
               3
               4
               5
               6
    Selezionate 10 righe.
    SQL>
    SQL> select column_value,count(*) occurences
      2  from table(get_arr)
      3  group by column_value
      4  order by column_value;
    COLUMN_VALUE OCCURENCES
               0          1
               1          2
               2          2
               3          2
               4          1
               5          1
               6          1
    Selezionate 7 righe.
    SQL> Bye Alessandro

  • Materialized views - query rewrite -- optional joins & dimensions

    Hi,
    I've implemented a number of materialized views that are accessible via query rewrite.
    Most of these views make use of duplicate tables (DD_TIME table is joined via purchase, load, process, ... date columns)
    I've also created a dimension to make Oracle aware of the time relation (month is child of year...)
    The issue:
    --> If I create the mat. view with inner joins, query rewrite works with the dimensions, but I need to provide ALL joined tables in the query
    --> If I create the mat. view with outer joins, query rewrite works even with 1 joined table, but the dimension seems to be ignored
    How can I create 'optional' joins in the Mat. View while making use of dimensions for rollup?
    (the limitations on materialized view delta joins mentioned on [oracle docs|http://docs.oracle.com/cd/B28359_01/server.111/b28313/qradv.htm#autoId16] kinda has me worried)
    Example Mat. View:
    CREATE MATERIALIZED VIEW DA_REPOSITORY_MERCHANT_MM
    ... ENABLE QUERY REWRITE
    AS SELECT
    DDFPC.YEAR_NO,
    DDFPC.YEAR_MONTH,
    DDPUR.YEAR_NO,
    DDPUR.YEAR_MONTH,
    SUM( DF.TRANSACTION_AMOUNT )
    FROM DF_REP DF,
    DD_TIME DDFPC,
    DD_TIME DDPUR
    WHERE DF.FPC_DTE = DDFPC.DAY_DATE(+)
    AND DF.PUR_DTE = DDPUR.DAY_DATE(+)
    GROUP BY
    DDFPC.YEAR_NO,
    DDFPC.YEAR_MONTH,
    DDPUR.YEAR_NO,
    DDPUR.YEAR_MONTH
    Example query launched:
    SELECT
    DDFPC.YEAR_NO,
    SUM( DF.TRANSACTION_AMOUNT )
    FROM DF_REP DF,
    DD_TIME DDFPC
    WHERE DF.FPC_DTE = DDFPC.DAY_DATE
    GROUP BY
    DDFPC.YEAR_NO

    The problem was resolved by setting foreign keys in the fact table and making them not nullable + using inner joins.
    --> this informs oracle there can be no difference between a query without the dimensions and a query with the dimensions.
    As a result, the materialized view can contain 1 fact linked to 2 dimension tables, but the query rewrite will work for queries on the 1 fact joined with only 1 dimension

  • Query rewrites with Nested materialized views with different aggregations

    Platform used : Oracle 11g.
    Here is a simple fact table (with measures m1,m2) and dimensions (a) Location (b) Calendar and (c) Product. The business problem is that aggregation operator for measure m1,m2 are different along location dimension and Calendar dimension. The intention is to preaggregate the measures for a product along the calendar dimension and Location dimension and store it as materialized views.
    The direct option is to define a materialized view with Inline queries (Because of the different aggrergation operator, it is not possible to write a query without Inline query). http://download-uk.oracle.com/docs/cd/B28359_01/server.111/b28313/qradv.htm#BABEAJBF documents the limitations that it works only for 'Text match' and 'Equivalent queries' and that is too limiting.
    So decided to have nested materialized view, with first view having just joins(my_dim_mvw_joins), the second view having aggregations along Calendar dimension (my_dim_mvw_calendar) and third view having aggregations along the Location dimension(my_dim_mvw_location). Obviously I do not want the query I fire to know about materialized views and I fire it against the fact table. I see that for the fired query (Which needs aggregations along both Calendar and Location), is rewritten with just second materialized view but not the third. (Had set QUERY_REWRITE_INTEGRITY as TRUSTED) .
    Wanted to know whether there are limitations on Query Writes with nested materialized views? Thanks
    (Have given a simple testable example below. Pls ignore the values given in 'CALENDAR_IDs', 'PRODUCT_IDs' etc as they are the same for all the queries)
    -- Calendar hierarchy table
    CREATE TABLE CALENDAR_HIERARCHY_TREE
    (     "CALENDAR_ID" NUMBER(5,0) NOT NULL ENABLE,
    "HIERARCHY1_ID" NUMBER(5,0),
    "HIERARCHY2_ID" NUMBER(5,0),
    "HIERARCHY3_ID" NUMBER(5,0),
    "HIERARCHY4_ID" NUMBER(5,0),
    CONSTRAINT "CALENDAR_HIERARCHY_TREE_PK" PRIMARY KEY ("CALENDAR_ID")
    -- Location hierarchy table
    CREATE TABLE LOCATION_HIERARCHY_TREE
    (     "LOCATION_ID" NUMBER(3,0) NOT NULL ENABLE,
    "HIERARCHY1_ID" NUMBER(3,0),
    "HIERARCHY2_ID" NUMBER(3,0),
    "HIERARCHY3_ID" NUMBER(3,0),
    "HIERARCHY4_ID" NUMBER(3,0),
    CONSTRAINT "LOCATION_HIERARCHY_TREE_PK" PRIMARY KEY ("LOCATION_ID")
    -- Product hierarchy table
    CREATE TABLE PRODUCT_HIERARCHY_TREE
    (     "PRODUCT_ID" NUMBER(3,0) NOT NULL ENABLE,
         "HIERARCHY1_ID" NUMBER(3,0),
         "HIERARCHY2_ID" NUMBER(3,0),
         "HIERARCHY3_ID" NUMBER(3,0),
         "HIERARCHY4_ID" NUMBER(3,0),
         "HIERARCHY5_ID" NUMBER(3,0),
         "HIERARCHY6_ID" NUMBER(3,0),
         CONSTRAINT "PRODUCT_HIERARCHY_TREE_PK" PRIMARY KEY ("PRODUCT_ID")
    -- Fact table
    CREATE TABLE RETAILER_SALES_TBL
    (     "PRODUCT_ID" NUMBER,
    "PRODUCT_KEY" VARCHAR2(50 BYTE),
    "PLAN_ID" NUMBER,
    "PLAN_PERIOD_ID" NUMBER,
    "PERIOD_ID" NUMBER(5,0),
    "M1" NUMBER,
    "M2" NUMBER,
    "M3" NUMBER,
    "M4" NUMBER,
    "M5" NUMBER,
    "M6" NUMBER,
    "M7" NUMBER,
    "M8" NUMBER,
    "LOCATION_ID" NUMBER(3,0),
    "M9" NUMBER,
    CONSTRAINT "RETAILER_SALES_TBL_LOCATI_FK1" FOREIGN KEY ("LOCATION_ID")
    REFERENCES LOCATION_HIERARCHY_TREE ("LOCATION_ID") ENABLE,
    CONSTRAINT "RETAILER_SALES_TBL_PRODUC_FK1" FOREIGN KEY ("PRODUCT_ID")
    REFERENCES PRODUCT_HIERARCHY_TREE ("PRODUCT_ID") ENABLE,
    CONSTRAINT "RETAILER_SALES_TBL_CALEND_FK1" FOREIGN KEY ("PERIOD_ID")
    REFERENCES CALENDAR_HIERARCHY_TREE ("CALENDAR_ID") ENABLE
    -- Location dimension definition to promote query rewrite
    create DIMENSION LOCATION_DIM
    LEVEL CHAIN IS LOCATION_HIERARCHY_TREE.HIERARCHY1_ID
    LEVEL CONSUMER_SEGMENT IS LOCATION_HIERARCHY_TREE.HIERARCHY3_ID
    LEVEL STORE IS LOCATION_HIERARCHY_TREE.LOCATION_ID
    LEVEL TRADING_AREA IS LOCATION_HIERARCHY_TREE.HIERARCHY2_ID
    HIERARCHY PROD_ROLLUP (
    STORE CHILD OF
    CONSUMER_SEGMENT CHILD OF
    TRADING_AREA CHILD OF
    CHAIN
    -- Calendar dimension definition
    create DIMENSION CALENDAR_DIM
    LEVEL MONTH IS CALENDAR_HIERARCHY_TREE.HIERARCHY3_ID
    LEVEL QUARTER IS CALENDAR_HIERARCHY_TREE.HIERARCHY2_ID
    LEVEL WEEK IS CALENDAR_HIERARCHY_TREE.CALENDAR_ID
    LEVEL YEAR IS CALENDAR_HIERARCHY_TREE.HIERARCHY1_ID
    HIERARCHY CALENDAR_ROLLUP (
    WEEK CHILD OF
    MONTH CHILD OF
    QUARTER CHILD OF
    YEAR
    -- Materialized view with just joins needed for other views
    CREATE MATERIALIZED VIEW my_dim_mvw_joins build immediate refresh complete enable query rewrite as
    select product_id, lht.HIERARCHY1_ID, lht.HIERARCHY2_ID, lht.HIERARCHY3_ID, lht.location_id, cht.HIERARCHY1_ID year,
    cht.HIERARCHY2_ID quarter, cht.HIERARCHY3_ID month, cht.calendar_id week, m1, m3, m7, m9
    from retailer_sales_tbl RS, calendar_hierarchy_tree cht, location_hierarchy_tree lht
    WHERE RS.period_id = cht.CALENDAR_ID
    and RS.location_id = lht.location_id
    and cht.CALENDAR_ID in (10,236,237,238,239,608,609,610,611,612,613,614,615,616,617,618,619,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477)
    AND product_id IN (5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20)
    AND lht.location_id IN (2, 3, 11, 12, 13, 14, 15, 4, 16, 17, 18, 19, 20)
    -- Materialized view which aggregate along calendar dimension
    CREATE MATERIALIZED VIEW my_dim_mvw_calendar build immediate refresh complete enable query rewrite as
    select product_id, HIERARCHY1_ID , HIERARCHY2_ID , HIERARCHY3_ID ,location_id, year, quarter, month, week,
    sum(m1) m1_total, sum(m3) m3_total, sum(m7) m7_total, sum(m9) m9_total,
    GROUPING_ID(product_id, location_id, year, quarter, month, week) dim_mvw_gid
    from my_dim_mvw_joins
    GROUP BY product_id, HIERARCHY1_ID , HIERARCHY2_ID , HIERARCHY3_ID , location_id,
    rollup (year, quarter, month, week);
    -- Materialized view which aggregate along Location dimension
    CREATE MATERIALIZED VIEW my_dim_mvw_location build immediate refresh complete enable query rewrite as
    select product_id, year, quarter, month, week, HIERARCHY1_ID, HIERARCHY2_ID, HIERARCHY3_ID, location_id,
    sum(m1_total) m1_total_1, sum(m3_total) m3_total_1, sum(m7_total) m7_total_1, sum(m9_total) m9_total_1,
    GROUPING_ID(product_id, HIERARCHY1_ID, HIERARCHY2_ID, HIERARCHY3_ID, location_id, year, quarter, month, week) dim_mvw_gid
    from my_dim_mvw_calendar
    GROUP BY product_id, year, quarter, month, week,
    rollup (HIERARCHY1_ID, HIERARCHY2_ID, HIERARCHY3_ID, location_id)
    -- SQL Query Fired (for simplicity have used SUM as aggregation operator for both, but they will be different)
    select product_id, year, HIERARCHY1_ID, HIERARCHY2_ID,
    sum(m1_total) m1_total_1, sum(m3_total) m3_total_1, sum(m7_total) m7_total_1, sum(m9_total) m9_total_1
    from
    select product_id, HIERARCHY1_ID , HIERARCHY2_ID , year,
    sum(m1) m1_total, sum(m3) m3_total, sum(m7) m7_total, sum(m9) m9_total
    from
    select product_id, lht.HIERARCHY1_ID , lht.HIERARCHY2_ID , lht.HIERARCHY3_ID ,lht.location_id, cht.HIERARCHY1_ID year, cht.HIERARCHY2_ID quarter, cht.HIERARCHY3_ID month, cht.calendar_id week,m1,m3,m7,m9
    from
    retailer_sales_tbl RS, calendar_hierarchy_tree cht, location_hierarchy_tree lht
    WHERE RS.period_id = cht.CALENDAR_ID
    and RS.location_id = lht.location_id
    and cht.CALENDAR_ID in (10,236,237,238,239,608,609,610,611,612,613,614,615,616,617,618,619,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477)
    AND product_id IN (5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20)
    AND lht.location_id IN (2, 3, 11, 12, 13, 14, 15, 4, 16, 17, 18, 19, 20)
    GROUP BY product_id, HIERARCHY1_ID , HIERARCHY2_ID , HIERARCHY3_ID , location_id, year
    ) sales_time
    GROUP BY product_id, year,HIERARCHY1_ID, HIERARCHY2_ID
    This Query rewrites only with my_dim_mvw_calendar. (as saw in Query Plan and EXPLAIN_MVIEW). But we would like it to use my_dim_mvw_location as that has aggregations for both dimensions.

    blackhole001 wrote:
    Hi all,
    I'm trying to make my programmer's life easier by creating a database view for them to query the data, so they don't have to worry about joining tables. This sounds like a pretty horrible idea. I say this because you will eventually end up with programmers that know nothing about your data model and how to properly interact with it.
    Additionally, what you will get is a developer that takes one of your views and see's that of the 20 columns in it, it has 4 that he needs. If all those 4 columns comes from a simple 2 table join, but the view has 8 tables, you're wasting a tonne of resources by using the view (and heaven forbid they have to join that view to another view to get 4 of the 20 columns from that other view as well).
    Ideally you'd write stored routines that satisfy exactly what is required (if you are the database resource and these other programmers are java, .net, etc... based) and the front end developers would call those routines customized for an exact purpose.
    Creating views is not bad, but it's by no means a proper solution to having developers not learn or understand SQL and/or the data model.

  • Query Rewrite ISSUE (ANSI JOINS do not work, traditional join works ) 11gR2

    For some types of queries constructed with ANSI JOINS, materialized views are not being used.
    This is currently increasing time on various reports since we cannot control the way the queries are generated(Tableau Application generates and runs queries against the STAR Schema).
    Have tried to debug this behavior using DBMS_MVIEW.EXPLAIN_REWRITE and mv_capabilities function without any success.
    The database is configured for query rewrite: REWRITE INTEGRITY, QUERY REWRITE ENABLED and other settings are in place.
    Have successfully reproduced the issue using SH Sample schema:
    Q1 and Q2 are logically identical the only difference between them being the type of join used:
    Q1: ANSI JOIN
    Q2: Traditional join
    Below is an example that can be validated on SH sample schema.
    Any help on this will be highly appreciated.
    -- Q1: the query is generated by an app and needs to be rewritten with materialized view
    SELECT cntr.country_subregion, cust.cust_year_of_birth, COUNT(DISTINCT cust.cust_first_name)
    FROM customers cust
    INNER JOIN countries cntr
       ON cust.country_id = cntr.country_id
    GROUP BY cntr.country_subregion, cust_year_of_birth;
    -- Q2: the query with traditional join is rewritten with materialized view
    SELECT cntr.country_subregion, cust.cust_year_of_birth, COUNT(DISTINCT cust.cust_first_name)
    FROM customers cust
    INNER JOIN countries cntr
       ON cust.country_id = cntr.country_id
    GROUP BY cntr.country_subregion, cust_year_of_birth;Tested both queries with the following materialized views:
    CREATE MATERIALIZED VIEW MVIEW_TEST_1
    ENABLE QUERY REWRITE
    AS
    SELECT cntr.country_subregion, cust.cust_year_of_birth, COUNT(DISTINCT cust.cust_first_name)
    FROM customers cust
    INNER JOIN countries cntr
       ON cust.country_id = cntr.country_id
    GROUP BY cntr.country_subregion, cust_year_of_birth;
    CREATE MATERIALIZED VIEW MVIEW_TEST_2
    ENABLE QUERY REWRITE
    AS
    SELECT cntr.country_subregion, cust.cust_year_of_birth, COUNT(DISTINCT cust.cust_first_name)
    FROM customers cust,  countries cntr
    WHERE cust.country_id = cntr.country_id
    GROUP BY cntr.country_subregion, cust_year_of_birth;Explain Plans showing that Q1 does not use materialized view and Q2 uses materialized view
    SET AUTOTRACE TRACEONLY
    --Q1 does not use MVIEW_TEST_1
    SQL> SELECT cntr.country_subregion, cust.cust_year_of_birth, COUNT(DISTINCT cust.cust_first_name)
    FROM customers cust
    INNER JOIN countries cntr
       ON cust.country_id = cntr.country_id
    GROUP BY cntr.country_subregion, cust_year_of_birth;  2    3    4    5 
    511 rows selected.
    Execution Plan
    Plan hash value: 1218164197
    | Id  | Operation           | Name       | Rows  | Bytes |TempSpc| Cost (%CPU)| Time       |
    |   0 | SELECT STATEMENT      |        |   425 | 12325 |       |   916   (1)| 00:00:11 |
    |   1 |  HASH GROUP BY           |        |   425 | 12325 |       |   916   (1)| 00:00:11 |
    |   2 |   VIEW                | VM_NWVW_1 | 55500 |  1571K|       |   916   (1)| 00:00:11 |
    |   3 |    HASH GROUP BY      |        | 55500 |  1842K|  2408K|   916   (1)| 00:00:11 |
    |*  4 |     HASH JOIN           |        | 55500 |  1842K|       |   409   (1)| 00:00:05 |
    |   5 |      TABLE ACCESS FULL| COUNTRIES |    23 |   414 |       |     3   (0)| 00:00:01 |
    |   6 |      TABLE ACCESS FULL| CUSTOMERS | 55500 |   867K|       |   405   (1)| 00:00:05 |
    --Q2 uses MVIEW_TEST_2
    SQL> SELECT cntr.country_subregion, cust.cust_year_of_birth, COUNT(DISTINCT cust.cust_first_name)
    FROM customers cust,  countries cntr
    WHERE cust.country_id = cntr.country_id
    GROUP BY cntr.country_subregion, cust_year_of_birth;  2    3    4 
    511 rows selected.
    Execution Plan
    Plan hash value: 2126022771
    | Id  | Operation               | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT          |              |     511 | 21973 |       3   (0)| 00:00:01 |
    |   1 |  MAT_VIEW REWRITE ACCESS FULL| MVIEW_TEST_2 |     511 | 21973 |       3   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------------Database version 11gR1 (Tested also on 11gR2)
    SQL> select * from v$version;
    BANNER
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    PL/SQL Release 11.2.0.1.0 - Production
    CORE     11.2.0.1.0     Production
    TNS for Linux: Version 11.2.0.1.0 - Production
    NLSRTL Version 11.2.0.1.0 - Production

    Thanks for the formatting tips.
    Just found an Oracle Bug which explains the above behavior.
    Unfortunately the bug will be fixed only in 12.1 Release so as a workaround will try to use traditional joins.
    For those who have metalink access see [Bug 10145667 : ERRORS TRYING TO REWRITE QUERY WITH EXACT TEXT MATCH TO MVIEW]

  • Materialized Views with Query Rewrite is not getting re-written

    I have tried everything that has been mentioned in all the forums here and on metalink to fix this issue, has any smart APEX user found a solution?
    The issue is the MV with Query rewrite capability is not being re-written.
    Things I have tried
    1) give all Query Rewrite privileges to all 3 APEx schemas and parsing schema;
    2) check trace files with tkprof;
    3) dynamically printed explain plan from v$_SQL on the page while executing the query;
    4) to test in a different environment i created an another DAD using the pl/sql webtool kit and tried the same thing and rewrite works like a charm...
    whats the issue here...why are apex schemas not re-writing the queries????
    appreciate any help...thanks

    Jes, per your request
    --create materialized view
    CREATE MATERIALIZED VIEW "RPLANSWEB"."MV_FCG_ALL_SUMMARY_TAB"
    ORGANIZATION HEAP PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
    STORAGE(INITIAL 81920 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "RPLANSWEB"
    BUILD IMMEDIATE
    USING INDEX
    REFRESH FORCE ON DEMAND
    USING DEFAULT LOCAL ROLLBACK SEGMENT
    ENABLE QUERY REWRITE
    AS SELECT fcg, year, fcg_desc,
    fac, efr, fac_desc, efr_desc,
    ums_round, fcg_allow_drillable allow_drillable,
    MAX(category_code_um1) category_code_um1,
    SUM(perm_asset) perm_asset,
    SUM(temp_asset) temp_asset,
    SUM(semi_asset) semi_asset,
    SUM(lease_asset) lease_asset,
    SUM(planned_constr) planned_constr,
    SUM(all_perm_asset) all_perm_asset,
    SUM(total_asset) total_asset,
    SUM(allow) allow, SUM(rqmt) rqmt,
    SUM(perm_planned_constr) perm_planned_constr,
    SUM(perm_planned_constr_rqmt_delta) perm_planned_constr_rqmt_delta,
    ROUND(DECODE(SUM(rqmt), 0, 0, SUM(all_perm_asset)/SUM(rqmt)*100)) perm_rqmt_pctsat,
    ROUND(DECODE(SUM(allow), 0, 0, SUM(all_perm_asset)/SUM(allow)*100)) perm_allw_pctsat,
    ROUND(DECODE(SUM(rqmt), 0, 0, SUM(total_asset)/SUM(rqmt)*100)) total_rqmt_pctsat,
    ROUND(DECODE(SUM(allow), 0, 0, SUM(total_asset)/SUM(allow)*100)) total_allw_pctsat,
    ROUND(DECODE(SUM(all_perm_asset), 0, 0, SUM(rqmt)/SUM(all_perm_asset)*100)) perm_rqmt_pctutl,
    ROUND(DECODE(SUM(all_perm_asset), 0, 0, SUM(allow)/SUM(all_perm_asset)*100)) perm_allw_pctutl,
    ROUND(DECODE(SUM(total_asset), 0, 0, SUM(rqmt)/SUM(total_asset)*100)) total_rqmt_pctutl,
    ROUND(DECODE(SUM(total_asset), 0, 0, SUM(allow)/SUM(total_asset)*100)) total_allw_pctutl,
    SUM(coarse_screen_asset) coarse_screen_asset,
    SUM(total_excess) total_excess,
    SUM(total_deficit) total_deficit,
    SUM(perm_excess) perm_excess,
    SUM(perm_deficit) perm_deficit,
    SUM(all_perm_excess) all_perm_excess,
    SUM(all_perm_deficit) all_perm_deficit,
    SUM(temp_excess) temp_excess,
    SUM(satisfy_rqmt) satisfy_rqmt
    FROM summary_tab_dd
    GROUP BY fcg, year, fcg_desc,
    fac, efr, fac_desc, efr_desc,
    ums_round, fcg_allow_drillable;
    sql plus> log in as parsing schema user (not APEX_PUBLIC_USER)
    sql plus> SELECT fcg, year, fcg_desc,
    SUM(perm_asset) perm_asset,
    SUM(perm_excess) perm_excess,
    SUM(perm_deficit) perm_deficit,
    SUM(all_perm_excess) all_perm_excess,
    SUM(all_perm_deficit) all_perm_deficit,
    SUM(temp_excess) temp_excess,
    SUM(satisfy_rqmt) satisfy_rqmt
    FROM summary_tab_dd
    where year=2007
    GROUP BY fcg, year, fcg_desc;
    --execution plan
    SELECT STATEMENT     ALL_ROWS     12     291     17460                         
    HASH(GROUP BY)          12     291     17460                         
    MAT_VIEW REWRITE ACCESS(FULL) RPLANSWEB.MV_FCG_ALL_SUMMARY_TAB     ANALYZED     11     291     17460                         "MV_FCG_ALL_SUMMARY_TAB"."YEAR"=2007
    --execution plan from sql workshop (application express)
    SELECT STATEMENT 42,341 55 3,882 1,990,027
    HASH GROUP BY 42,341 55 3,882 1,990,027
    TABLE ACCESS FULL SUMMARY_TAB_DD 109,158 47 3,329 5,130,426 "YEAR" = 2007
    --execution plan from an APEX page (displayed from v$sql and V$SQL_PLAN)
    OPERATION: SELECT STATEMENT OPTIONS: OBJECT_NAME: OBJECT_ALIAS: OBJECT_TYPE: OPTIMIZER: ALL_ROWS SEARCH_COLUMNS: 0 COST: 4600 CARDINALITY: BYTES: CPU_COST: IO_COST: ACCESS_PREDICATES: FILTER_PREDICATES: PROJECTION:
    OPERATION: HASH OPTIONS: GROUP BY OBJECT_NAME: OBJECT_ALIAS: OBJECT_TYPE: OPTIMIZER: SEARCH_COLUMNS: 0 COST: 4600 CARDINALITY: 109158 BYTES: 8732640 CPU_COST: 549150132 IO_COST: 4569 ACCESS_PREDICATES: FILTER_PREDICATES: PROJECTION: "FCG"[VARCHAR2,6], "FCG_DESC"[VARCHAR2,15], SUM("PERM_DEFICIT")[22], SUM("PERM_EXCESS")[22], SUM("SATISFY_RQMT")[22], SUM("TEMP_EXCESS")[22], SUM("ALL_PERM_EXCESS")[22], SUM("ALL_PERM_DEFICIT")[22], SUM("PERM_ASSET")[22]
    OPERATION: TABLE ACCESS OPTIONS: FULL OBJECT_NAME: SUMMARY_TAB_DD OBJECT_ALIAS: SUMMARY_TAB_DD@SEL$1 OBJECT_TYPE: TABLE OPTIMIZER: SEARCH_COLUMNS: 0 COST: 3329
    as you can see while executing the script in sql developer the optimizer is finding the relevant materialized view, not in the case of APEX's SQL Workshop or Page.
    appreciate your time

  • Query rewrite does not happen

    Hello all,
    let me start by wishing you all the best for the forthcoming year !
    And now, the problem
    I am trying to create a materialized view so that a few slow reports that run on OBIEE (10g) make use of query rewrite functionality. Unfortunately any attempt that had made was unsuccessful. I though of posting the query that is created by OBIEE and the different materialized views that i have created, so that anyone that had a similar problem before might help me through it.  So here it goes ( there is a separate discussion for the other query here ) :
    First comes the query that was created by OBIEE when no materialized view existed.
      SELECT DISTINCT D1.c5 AS c1,                  D1.c10 AS c2,                       D1.c9 AS c3,                  D1.c6 AS c4,                  D1.c8 AS c5,                  D1.c8 / NULLIF (D1.c6, 0) AS c6,
                      D1.c7 AS c7,                  D1.c7 / NULLIF (D1.c6, 0) AS c8,        D1.c4 AS c9,                  D1.c3 / NULLIF (D1.c1, 0) AS c10,                     D1.c2 / NULLIF (D1.c1, 0) AS c11
        FROM (SELECT SUM (D1.c6) OVER (PARTITION BY D1.c5) AS c1,
                     SUM (D1.c7) OVER (PARTITION BY D1.c5) AS c2,
                     SUM (D1.c8) OVER (PARTITION BY D1.c5) AS c3,
                     SUM (D1.c4) OVER (PARTITION BY D1.c5) AS c4,
                     D1.c5 AS c5,                 D1.c6 AS c6,                 D1.c7 AS c7,                 D1.c8 AS c8,                 D1.c9 AS c9,                 D1.c10 AS c10
                FROM (  SELECT COUNT (CASE D1.c12 WHEN 1 THEN D1.c11 ELSE NULL END)    AS c4,                    D1.c5 AS c5,                           SUM (D1.c13) AS c6,            
                             SUM (D1.c14) AS c7,                           SUM (D1.c15) AS c8,               COUNT (DISTINCT D1.c11) AS c9,                           D1.c10 AS c10
                          FROM (SELECT                   /*+ PARALLEL(T16913,8) */
                                      T19403.YEAR_MONTH   AS c5,
                                       T7252.PERCENTAGE AS c10,
                                       T366.BARCODE AS c11,
                                       ROW_NUMBER ()   OVER (  PARTITION BY T19403.YEAR_MONTH,   T366.BARCODE  ORDER BY  T19403.YEAR_MONTH DESC,   T366.BARCODE DESC)  AS c12,
                                       T16913.PHA_QUANTITY AS c13,
                                       T16913.EXEC_COST AS c14,
                                       T16913.EXEC_VALUE AS c15
                                  FROM EXECALENDAR_DIM T19403,
                                           DRUG_DIM T366,
                                           PERCENTAGE_DIM T7252,
                                           PRESCDRUG_FACT T16913
                                 WHERE (T366.DWHKEY = T16913.DRU_DWHKEY
                                        AND T7252.DWHKEY = T16913.PER_DWHKEY
                                        AND T16913.EXECUTION_DATE =
                                               T19403.CALENDAR_DATE
                                        AND T19403.YEAR_MONTH = '201212')) D1
                      GROUP BY D1.c5, D1.c10) D1) D1
    ORDER BY c1, c2
    so my first try was that
    CREATE MATERIALIZED VIEW PRESCDRUG_FACT_MV  BUILD IMMEDIATE  REFRESH ON DEMAND  ENABLE QUERY REWRITE  AS
    SELECT  /*+ PARALLEL(PRESCDRUG_FACT,8) */
                     EXECALENDAR_DIM.YEAR_MONTH       as  YEAR_MONTH
                    ,PRESCDRUG_FACT.PER_DWHKEY
                     ,count(*)                            as COUNT_ALL
                     ,COUNT (EXECALENDAR_DIM.YEAR_MONTH)  AS c_YEAR_MONTH
                     ,COUNT (DISTINCT PRESCDRUG_FACT.DRUG_CD) DRUG_CODE
                     ,COUNT (DISTINCT PRESCDRUG_FACT.DRUG_BARCODE) BARCODE
                      -- quantities
                     ,SUM (PRESCDRUG_FACT.PHA_QUANTITY) AS PHA_QUANTITY
                     ,SUM (PRESCDRUG_FACT.DOC_QUANTITY) AS DOC_QUANTITY
                     ,SUM (PRESCDRUG_FACT.APR_QUANTITY) AS APR_QUANTITY
                     -- values
                     ,SUM (PRESCDRUG_FACT.EXEC_VALUE)       AS EXEC_VALUE
                     ,SUM (PRESCDRUG_FACT.PUB_VALUE)        AS PUB_VALUE                
                     ,SUM (PRESCDRUG_FACT.APR_VALUE) AS APR_VALUE                
                     -- costs
                     ,SUM (PRESCDRUG_FACT.EXEC_COST) AS EXEC_COST
                     ,SUM (PRESCDRUG_FACT.PUB_COST) AS PUB_COST
                     ,SUM (PRESCDRUG_FACT.APR_COST) AS APR_COST
       FROM  EXECALENDAR_DIM,    PRESCDRUG_FACT
      WHERE EXECALENDAR_DIM.CALENDAR_DATE   = PRESCDRUG_FACT.EXECUTION_DATE
           AND EXECALENDAR_DIM.YEAR_MONTH in ( '201212')
       GROUP BY   EXECALENDAR_DIM.YEAR_MONTH ,PRESCDRUG_FACT.PER_DWHKEY
    and i got the following messages from DBMS_MVIEW.EXPLAIN_REWRITE
    QSM-01150: query did not rewrite
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, EXECALENDAR_DIM, on column, CALENDAR_DATE
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, EXECUTION_DATE
    QSM-01082: Joining materialized view, PRESCDRUG_FACT_MV, with table, PRESCDRUG_FACT, not possible
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, DRU_DWHKEY
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, EXEC_VALUE
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, EXEC_COST
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, PHA_QUANTITY
    QSM-01155: multi-mv query rewrite not possible when there is a Window Function
    QSM-01219: no suitable materialized view found to rewrite this query
    My second attempt is the following ( in comparison to the first i have added the DRUG_BARCODE column in the grouping clause
    CREATE MATERIALIZED VIEW PRESCDRUG_FACT_MV BUILD IMMEDIATE  REFRESH ON DEMAND ENABLE QUERY REWRITE  AS
    SELECT  /*+ PARALLEL(PRESCDRUG_FACT,8) */
                     EXECALENDAR_DIM.YEAR_MONTH       as  YEAR_MONTH
                     ,PRESCDRUG_FACT.PER_DWHKEY
                  ,PRESCDRUG_FACT.DRUG_BARCODE
                     ,count(*)                                            as COUNT_ALL
                     ,COUNT (EXECALENDAR_DIM.YEAR_MONTH)  AS c_YEAR_MONTH
                     ,COUNT (DISTINCT PRESCDRUG_FACT.DRUG_CD) DRUG_CODE
                     ,COUNT (DISTINCT PRESCDRUG_FACT.DRUG_BARCODE) BARCODE
                     ,COUNT (DISTINCT PRESCDRUG_FACT.PRESC_NUMBER) PRESC_NUMBER
                     ,COUNT (DISTINCT PRESCDRUG_FACT.PRESC_ID)  PRESC_ID
                      -- quantities
                     ,SUM (PRESCDRUG_FACT.PHA_QUANTITY) AS PHA_QUANTITY
                     ,SUM (PRESCDRUG_FACT.DOC_QUANTITY)        AS DOC_QUANTITY
                     ,SUM (PRESCDRUG_FACT.APR_QUANTITY) AS APR_QUANTITY
                     -- values
                     ,SUM (PRESCDRUG_FACT.EXEC_VALUE)       AS EXEC_VALUE
                     ,SUM (PRESCDRUG_FACT.PUB_VALUE)        AS PUB_VALUE                
                     ,SUM (PRESCDRUG_FACT.APR_VALUE) AS APR_VALUE                
                     -- costs
                     ,SUM (PRESCDRUG_FACT.EXEC_COST) AS EXEC_COST
                     ,SUM (PRESCDRUG_FACT.PUB_COST) AS PUB_COST
                     ,SUM (PRESCDRUG_FACT.APR_COST) AS APR_COST
        FROM  EXECALENDAR_DIM,    PRESCDRUG_FACT
      WHERE EXECALENDAR_DIM.CALENDAR_DATE   = PRESCDRUG_FACT.EXECUTION_DATE
           AND EXECALENDAR_DIM.YEAR_MONTH in ( '201212')
       GROUP BY   EXECALENDAR_DIM.YEAR_MONTH ,PRESCDRUG_FACT.PER_DWHKEY,DRUG_BARCODE
    and the results of DBMS_MVIEW.EXPLAIN_REWRITE
    QSM-01150: query did not rewrite
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, EXECALENDAR_DIM, on column, CALENDAR_DATE
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, EXECUTION_DATE
    QSM-01082: Joining materialized view, PRESCDRUG_FACT_MV, with table, PRESCDRUG_FACT, not possible
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, DRU_DWHKEY
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, EXEC_VALUE
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, EXEC_COST
    QSM-01102: materialized view, PRESCDRUG_FACT_MV, requires join back to table, PRESCDRUG_FACT, on column, PHA_QUANTITY
    QSM-01155: multi-mv query rewrite not possible when there is a Window Function
    QSM-01219: no suitable materialized view found to rewrite this query
    third try (rolling up the group results)
    CREATE MATERIALIZED VIEW PRESCDRUG_FACT_MV BUILD IMMEDIATE  REFRESH ON DEMAND ENABLE QUERY REWRITE  AS
    SELECT  /*+ PARALLEL(PRESCDRUG_FACT,8) */
                     EXECALENDAR_DIM.YEAR_MONTH       as  YEAR_MONTH
                     ,PRESCDRUG_FACT.PER_DWHKEY
                  ,PRESCDRUG_FACT.DRUG_BARCODE
                     ,count(*)                                            as COUNT_ALL
                     ,COUNT (EXECALENDAR_DIM.YEAR_MONTH)  AS c_YEAR_MONTH
                     ,COUNT (DISTINCT PRESCDRUG_FACT.DRUG_CD) DRUG_CODE
                     ,COUNT (DISTINCT PRESCDRUG_FACT.DRUG_BARCODE) BARCODE
                     ,COUNT (DISTINCT PRESCDRUG_FACT.PRESC_NUMBER) PRESC_NUMBER
                     ,COUNT (DISTINCT PRESCDRUG_FACT.PRESC_ID)  PRESC_ID
                      -- quantities
                     ,SUM (PRESCDRUG_FACT.PHA_QUANTITY) AS PHA_QUANTITY
                     ,SUM (PRESCDRUG_FACT.DOC_QUANTITY)        AS DOC_QUANTITY
                     ,SUM (PRESCDRUG_FACT.APR_QUANTITY) AS APR_QUANTITY
                     -- values
                     ,SUM (PRESCDRUG_FACT.EXEC_VALUE)       AS EXEC_VALUE
                     ,SUM (PRESCDRUG_FACT.PUB_VALUE)        AS PUB_VALUE                
                     ,SUM (PRESCDRUG_FACT.APR_VALUE) AS APR_VALUE                
                     -- costs
                     ,SUM (PRESCDRUG_FACT.EXEC_COST) AS EXEC_COST
                     ,SUM (PRESCDRUG_FACT.PUB_COST) AS PUB_COST
                     ,SUM (PRESCDRUG_FACT.APR_COST) AS APR_COST
        FROM  EXECALENDAR_DIM,    PRESCDRUG_FACT
      WHERE EXECALENDAR_DIM.CALENDAR_DATE   = PRESCDRUG_FACT.EXECUTION_DATE
           AND EXECALENDAR_DIM.YEAR_MONTH in ( '201212')
       GROUP BY   EXECALENDAR_DIM.YEAR_MONTH     , rollup (PRESCDRUG_FACT.PER_DWHKEY,    DRUG_BARCODE) 
    results from DBMS_MVIEW.EXPLAIN_REWRITE
    QSM-01150: query did not rewrite
    QSM-01295: no suitable grouping_id found in materialized view with grouping sets
    QSM-01155: multi-mv query rewrite not possible when there is a Window Function
    QSM-01219: no suitable materialized view found to rewrite this query  
    So, no luck so far. My guess is that it has to do something with the partition clause that appears in the original query.
    anyway, if anything cross your minds..
    thanks in advance
    Theodore

    Hello again,
    It appeared that, the problem is present only when I try the query in pl/sql developer.
    For some reason, even though I set QUERY_REWRITE_INTEGRITY to STALE_TOLERATED, it behaved as this parameter was set to ENFORCED.
    So the case was that:
    for session - STALE_TOLERATED
    for system - ENFORCED
    In v$parameter2 against "QUERY_REWRITE_INTEGRITY" was shown "stale_tolerated", but the query was not rewritten.
    When I do the same (altering the session and perform the select query) in SQLPlus, everything works as expected - the query is rewritten.
    And I conclude the problem is in PL/SQL Developer (my version is 8.0.1.1498) or something related to this.
    Edited by: Verdi on 2010-2-12 14:00

  • Query Rewrite with regular database Views

    Hi all,
    I'm trying to make my programmer's life easier by creating a database view for them to query the data, so they don't have to worry about joining tables. However, query rewrite doesn't work no matter how I define the MV and View. Here's an example:
    I've Sales tables with columns: PDate, CustCode, Amount
    and Customer table with columns: CustCode, CustDesc
    I create a view SALES_V with columns: PDate, CustCode, CustDesc, Amount by joining Sales table with Customer table as follows:
    create or replace view SALES_V as
    select PDate, c.CustCode, c.CustDesc, Amount
    from Sales s
    join Customer c on (s.CustCode=c.CustCode);
    For the sake of speed, I create a materialized view SALES_TOT_MV with columns: PDate, Amount with the following SQL:
    create materialized view SALES_TOT_MV
    enable query rewrite
    as select PDate, sum(Amount) Amount from Sales
    group by PDate;
    When I run the following query, I expect it to be rewritten to make use of SALES_TOT_MV:
    select PDate, sum(Amount) from SALES_V
    group by PDate;
    However, explain plan always tell me it's using SALES table, not the SALES_TOT_MV.
    Can somebody tell me it's a limitation of Oracle optimizer or I'm just missing something for this?
    Thanks in advance!!
    - Andrew
    Edited by: blackhole001 on Jan 28, 2010 12:34 PM

    blackhole001 wrote:
    Hi all,
    I'm trying to make my programmer's life easier by creating a database view for them to query the data, so they don't have to worry about joining tables. This sounds like a pretty horrible idea. I say this because you will eventually end up with programmers that know nothing about your data model and how to properly interact with it.
    Additionally, what you will get is a developer that takes one of your views and see's that of the 20 columns in it, it has 4 that he needs. If all those 4 columns comes from a simple 2 table join, but the view has 8 tables, you're wasting a tonne of resources by using the view (and heaven forbid they have to join that view to another view to get 4 of the 20 columns from that other view as well).
    Ideally you'd write stored routines that satisfy exactly what is required (if you are the database resource and these other programmers are java, .net, etc... based) and the front end developers would call those routines customized for an exact purpose.
    Creating views is not bad, but it's by no means a proper solution to having developers not learn or understand SQL and/or the data model.

  • Materialized views on prebuilt tables - query rewrite

    Hi Everyone,
    I am currently counting on implementing the query rewrite functionality via materialized views to leverage existing aggregated tables.
    Goal*: to use aggregate-awareness for our queries
    How*: by creating views on existing aggregates loaded via ETL (+CREATE MATERIALIZED VIEW xxx on ON PREBUILT TABLE ENABLE QUERY REWRITE+)
    Advantage*: leverage oracle functionalities + render logical model simpler (no aggregates)
    Disadvantage*: existing ETL's need to be written as SQL in view creation statement --> aggregation rule exists twice (once on db, once in ETL)
    Issue*: Certain ETL's are quite complex via lookups, functions, ... --> might create overy complex SQLs in view creation statements
    My question: is there a way around the issue described? (I'm assuming the SQL in the view creation is necessary for oracle to know when an aggregate can be used)
    Best practices & shared experiences are welcome as well of course
    Kind regards,
    Peter

    streefpo wrote:
    I'm still in the process of testing, but the drops should not be necessary.
    Remember: The materialized view is nothing but a definition - the table itself continues to exist as before.
    So as long as the definition doesn't change (added column, changed calculation, ...), the materialized view doesn't need to be re-created. (as the data is not maintained by Oracle)Thanks for reminding me but if you find a documented approach I will be waiting because this was the basis of my argument from the beginning.
    SQL> select * from v$version ;
    BANNER                                                                                                                                                                    
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production                                                                                                    
    PL/SQL Release 11.2.0.1.0 - Production                                                                                                                                    
    CORE     11.2.0.1.0     Production                                                                                                                                                
    TNS for Linux: Version 11.2.0.1.0 - Production                                                                                                                            
    NLSRTL Version 11.2.0.1.0 - Production                                                                                                                                    
    SQL> desc employees
    Name                                                                                            Null?    Type
    EMPLOYEE_ID                                                                                     NOT NULL NUMBER(6)
    FIRST_NAME                                                                                               VARCHAR2(20)
    LAST_NAME                                                                                       NOT NULL VARCHAR2(25)
    EMAIL                                                                                           NOT NULL VARCHAR2(25)
    PHONE_NUMBER                                                                                             VARCHAR2(20)
    HIRE_DATE                                                                                       NOT NULL DATE
    JOB_ID                                                                                          NOT NULL VARCHAR2(10)
    SALARY                                                                                                   NUMBER(8,2)
    COMMISSION_PCT                                                                                           NUMBER(2,2)
    MANAGER_ID                                                                                               NUMBER(6)
    DEPARTMENT_ID                                                                                            NUMBER(4)
    SQL> select count(*) from employees ;
      COUNT(*)                                                                                                                                                                
           107                                                                                                                                                                
    SQL> create table mv_table nologging as select department_id, sum(salary) as totalsal from employees group by department_id ;
    Table created.
    SQL> desc mv_table
    Name                                                                                            Null?    Type
    DEPARTMENT_ID                                                                                            NUMBER(4)
    TOTALSAL                                                                                                 NUMBER
    SQL> select count(*) from mv_table ;
      COUNT(*)                                                                                                                                                                
            12                                                                                                                                                                
    SQL> create materialized view mv_table on prebuilt table with reduced precision enable query rewrite as select department_id, sum(salary) as totalsal from employees group by department_id ;
    Materialized view created.
    SQL> select count(*) from mv_table ;
      COUNT(*)                                                                                                                                                                
            12                                                                                                                                                                
    SQL> select object_name, object_type from user_objects where object_name = 'MV_TABLE' ;
    OBJECT_NAME                                                                                                                      OBJECT_TYPE                              
    MV_TABLE                                                                                                                         TABLE                                    
    MV_TABLE                                                                                                                         MATERIALIZED VIEW                        
    SQL> insert into mv_table values (999, 100) ;
    insert into mv_table values (999, 100)
    ERROR at line 1:
    ORA-01732: data manipulation operation not legal on this view
    SQL> update mv_table set totalsal = totalsal * 1.1 where department_id = 10 ;
    update mv_table set totalsal = totalsal * 1.1 where department_id = 10
    ERROR at line 1:
    ORA-01732: data manipulation operation not legal on this view
    SQL> delete from mv_table where totalsal <= 10000 ;
    delete from mv_table where totalsal <= 10000
    ERROR at line 1:
    ORA-01732: data manipulation operation not legal on this view While investigating for this thread I actually made my own question redundant as the answer became gradually clear:
    When using complex ETL's, I just need to make sure the complexity is located in the ETL loading the detailed table, not the aggregate
    I'll try to clarify through an example:
    - A detailed Table DET_SALES exists with Sales per Day, Store & Product
    - An aggregated table AGG_SALES_MM exists with Sales, SalesStore per Month, Store & Product
    - An ETL exists to load AGG_SALES_MM where Sales = SUM(Sales) & SalesStore = (SUM(Sales) Across Store)
    --> i.e. the SalesStore measure will be derived out of a lookup
    - A (Prebuilt) Materialized View will exist with the same column definitions as the ETL
    --> to allow query-rewrite to know when to access the table
    My concern was how to include the SalesStore in the materialized view definition (--> complex SQL!)
    --> I should actually include SalesStore in the DET_SALES table, thus:
    - including the 'Across Store' function in the detailed ETL
    - rendering my Aggregation ETL into a simple GROUP BY
    - rendering my materialized view definition into a simple GROUP BY as wellNot sure how close your example is to your actual problem. Also don't know if you are doing an incremental/complete data load and the data volume.
    But the "SalesStore = (SUM(Sales) Across Store)" can be derived from the aggregated MV using analytical function. One can just create a normal view on top of MV for querying. It is hard to believe that aggregating in detail table during ETL load is the best approach but what do I know?

  • Materialized views - schedule, indexes, query rewrite, etc.

    I'm trying to get the hang of materialized views and need some help . . .
    running Oracle 10gR2
    I created a materialized view as follows:
    CREATE MATERIALIZED VIEW "MY_SCHEMA"."USERS"
    AS
    SELECT * FROM "USERS"@PRODUCTION -- to copy the USERS table from my production database to this database
    Worked fine. So far so good. Then, I altered it to schedule the refresh:
    ALTER MATERIALIZED VIEW "MY_SCHEMA"."USERS" REFRESH FORCE START WITH SYSDATE NEXT TRUNC(SYSDATE + 1) + 4/24
    -- to schedule a refresh immediately (SYSDATE) and every morning thereafter at 4:00 am (I think)
    then, I wanted to enable query rewrite, so I issued the following command:
    ALTER MATERIALIZED VIEW "MY_SCHEMA"."USERS" ENABLE QUERY REWRITE;
    and I got the
    ALTER MATERIALIZED VIEW succeeded.
    message for both of those commands (I'm doing this in SQL Developer).
    Then, I edit the materialized view in SQL Developer, click on the 'SQL' tab, and get the following:
    CREATE MATERIALIZED VIEW "MY_SCHEMA"."USERS"
    ORGANIZATION HEAP PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "TBLSPC_PHIGH"
    BUILD IMMEDIATE
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "TBLSPC_PHIGH"
    REFRESH FORCE ON DEMAND START WITH sysdate+0 NEXT TRUNC(SYSDATE + 1) + 4/24
    WITH PRIMARY KEY USING DEFAULT LOCAL ROLLBACK SEGMENT
    DISABLE QUERY REWRITE
    AS SELECT "USERS"."User" "User","USERS"."Logon" "Logon","USERS"."Name" "Name","USERS"."Password"
    "Password","USERS"."Level" "Level","USERS"."Producer" "Producer","USERS"."Deleted" "Deleted","USERS"."ClaimDoctor"
    "ClaimDoctor","USERS"."UserType" "UserType","USERS"."Locked" "Locked","USERS"."Scheduler"
    "Scheduler","USERS"."RestrictDays" "RestrictDays","USERS"."First" "First","USERS"."DisableAutoChart"
    "DisableAutoChart","USERS"."MaxChartOut" "MaxChartOut","USERS"."MaxHoursOut" "MaxHoursOut","USERS"."EffDate"
    "EffDate","USERS"."ExpDate" "ExpDate","USERS"."SwipeLogon" "SwipeLogon","USERS"."SwipePassword"
    "SwipePassword","USERS"."PwdLastChanged" "PwdLastChanged","USERS"."Audit" "Audit","USERS"."IsInstructor"
    "IsInstructor" FROM "USERS"@PRODUCTION.REGRESS.RDBMS.DEV.US.ORACLE.COM "USERS";
    The problems I've encountered so far:
    1) I created this two days ago and changed the value of one column in one row in the 'source' USERS table
    (USERS@PRODUCTION) as a test case. So far, that change has not propagated over to my materialized view even though
    it has had two chances to do so (yesterday morning at 4:00 am and this morning at 4:00 am).
    2) I enabled QUERY REWRITE. Why does it still show DISABLE?
    3) The primary key of the table came over (as far as I can tell) because it shows in SQL Developer. However, the
    indexed columns are no longer indexed. Do I need to recreate those indexes manually and will they persist?
    4) As you have guessed, I have just taken the plunge into materialized views, and have not been able to find
    anything on the Web along the lines of 'Materialized Views for Dummies'. So, any and all advice/suggestions/help
    will be welcome.
    Thanks,
    Carl

    The Refresh would be executed by a job submitted in the background.
    Query USER_JOBS (or DBA_JOBS) to see if a job has been submitted and if it has been running (you'd be able to see LAST_DATE, LAST_SEC and NEXT_DATE and NEXT_SEC). \
    If the Refresh job has been failing the FAILURES count would be incremented. If there are 16 consecutive failures, the job is marked BROKEN. (if a job fails, Oracle retries it automatically and keeps retrying till it is BROKEN). If the job has been failing you would get messages in the database instance alert log file and trace files.
    If the Refresh job has not been running check the parameter value for JOB_QUEUE_PROCESSES -- a value of 0 would not run in jobs in the USER_JOBS/DBA_JOBS view. Ask the DBA to increase set this parameter to at least 1.
    Hemant K Chitale
    http://hemantoracledba.blogspot.com

  • Query rewrite don't work wor aggregate query but work for join query

    Dear experts,
    Let me know what's wrong for
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    I have two MATERIALIZED VIEW:
    A) -- Only join
    CREATE MATERIALIZED VIEW "SCOTT"."TST_MV"
    ENABLE QUERY REWRITE AS
    SELECT "T57410"."MEMBER_KEY" "MEMBER_KEY",
    "T57410"."ANCESTOR_KEY" "ANCESTOR_KEY",
    "T57410"."DISTANCE" "DISTANCE",
    "T57410"."IS_LEAF" "IS_LEAF",
    "T57460"."DEPARTMENTID" "DEPARTMENTID",
    "T57460"."NAME" "NAME","T57460"."PARENT"
    "PARENT","T57460"."SHORTNAME" "SHORTNAME",
    "T57460"."SKIMOID" "SKIMOID"
    FROM "BI_OIV_HIER" "T57410",
    "BI_DEPARTMENTS" "T57460"
    WHERE "T57410"."ANCESTOR_KEY"="T57460"."DEPARTMENTID";
    B) -- Join with aggregation
    CREATE MATERIALIZED VIEW "SCOTT"."TST_MV2"
    ("C41", "C42", "C43",
    "C44", "C45", "C46",
    "C47", "C48", "C49",
    "C50", "C51", "C52",
    "C53", "C54", "C55",
    "C56", "C57", "C58",
    "C59", "C60", "C61",
    "INCIDENTTYPE")
    ENABLE QUERY REWRITE
    AS SELECT COUNT(T56454.TOTAL) AS c41,
    T56840.CATEGORYID AS c42,
    T56840.PARENT AS c43,
    T56908.DOCSTATEID AS c44,
    T56908.PARENT AS c45,
    T56947.EXPIREDID AS c46,
    T56947.PARENT AS c47,
    T56986.ISSUESTATEID AS c48,
    T56986.PARENT AS c49,
    T57025.LOCATIONID AS c50,
    T57025.PARENT AS c51,
    T57064.NEWID AS c52,
    T57064.PARENT AS c53,
    T57103.PARENT AS c54,
    T57103.RESOLUTIONID AS c55,
    T57142.PARENT AS c56,
    T57142.RESPONSIBLEID AS c57,
    T57181.PARENT AS c58,
    T57181.SOURCEID AS c59,
    T57460.DEPARTMENTID AS c60,
    T57460.PARENT AS c61,
    T56454.INCIDENTTYPE
    FROM BI_OIV_HIER T57410
    BI_DEPARTMENTS T57460
    BI_SOURCE_HIER T57176
    SOURCE T57181
    BI_RESPONSIBLE_HIER T57137
    RESPONSIBLE T57142
    BI_RESOLUTIONS_HIER T57098
    RESOLUTIONS T57103
    BI_NEW_HIER T57059
    NEW T57064
    BI_LOCATIONS_HIER T57020
    LOCATIONS T57025
    BI_ISSUESTATES_HIER T56981
    ISSUESTATES T56986
    BI_EXPIRED_HIER T56942
    EXPIRED T56947
    BI_DOCSTATES_HIER T56903
    DOCSTATES T56908
    BI_CATEGORY_HIER T56835
    CATEGORY T56840
    INCIDENTS T56454
    WHERE ( T56454.RESOLUTION = T57098.MEMBER_KEY
    AND T56454.CATEGORY = T56835.MEMBER_KEY
    AND T56454.DOCSTATE = T56903.MEMBER_KEY
    AND T56454.EXPIRED = T56942.MEMBER_KEY
    AND T56454.ISSUESTATE = T56981.MEMBER_KEY
    AND T56454.LOCATION = T57020.MEMBER_KEY
    AND T56454.NEW = T57059.MEMBER_KEY
    AND T56454.RESPONSIBLE = T57137.MEMBER_KEY
    AND T56454.SOURCE = T57176.MEMBER_KEY
    AND T56454.DEPARTMENTID = T57410.MEMBER_KEY
    AND T56835.ANCESTOR_KEY = T56840.CATEGORYID
    AND T56903.ANCESTOR_KEY = T56908.DOCSTATEID
    AND T56942.ANCESTOR_KEY = T56947.EXPIREDID
    AND T56981.ANCESTOR_KEY = T56986.ISSUESTATEID
    AND T57020.ANCESTOR_KEY = T57025.LOCATIONID
    AND T57059.ANCESTOR_KEY = T57064.NEWID
    AND T57098.ANCESTOR_KEY = T57103.RESOLUTIONID
    AND T57137.ANCESTOR_KEY = T57142.RESPONSIBLEID
    AND T57176.ANCESTOR_KEY = T57181.SOURCEID
    AND T57410.ANCESTOR_KEY = T57460.DEPARTMENTID
    GROUP BY T56840.CATEGORYID,
    T56840.PARENT,
    T56908.DOCSTATEID,
    T56908.PARENT,
    T56947.EXPIREDID,
    T56947.PARENT,
    T56986.ISSUESTATEID,
    T56986.PARENT,
    T57025.LOCATIONID,
    T57025.PARENT,
    T57064.NEWID,
    T57064.PARENT,
    T57103.PARENT,
    T57103.RESOLUTIONID,
    T57142.PARENT,
    T57142.RESPONSIBLEID,
    T57181.PARENT,
    T57181.SOURCEID,
    T57460.DEPARTMENTID,
    T57460.PARENT,
    T56454.INCIDENTTYPE;
    So, optimizer uses query rewrite in
    select * from TST_MV
    and don't use query rewrite in
    select * from TST_MV2
    within one session.
    select * from TST_MV should be read as underlying select for TST_MV:
    SELECT "T57410"."MEMBER_KEY" "MEMBER_KEY",
    "T57410"."ANCESTOR_KEY" "ANCESTOR_KEY",
    "T57410"."DISTANCE" "DISTANCE",
    "T57410"."IS_LEAF" "IS_LEAF",
    "T57460"."DEPARTMENTID" "DEPARTMENTID",
    "T57460"."NAME" "NAME","T57460"."PARENT"
    "PARENT","T57460"."SHORTNAME" "SHORTNAME",
    "T57460"."SKIMOID" "SKIMOID"
    FROM "BI_OIV_HIER" "T57410",
    "BI_DEPARTMENTS" "T57460"
    WHERE "T57410"."ANCESTOR_KEY"="T57460"."DEPARTMENTID";
    So, select * from TST_MV2 should be read by similar way as underlying select to TST_MV2
    DBMS_STATS.GATHER_TABLE_STAT is done for each table and MV.
    Please help to investigate the issue.
    Why TST_MV2 don't used for query rewrite ?
    Kind regards.

    Hi Carlos
    It looks like you have more than one question in your posting. Would I be right in saying that you have an issue with how long Discoverer takes when compared with SQL, and a second issue with regards to MVs not being used? I will add some comments on both. If one of these is not an issue please inform.
    Issue 1:
    Have you compared the explain plan from Discoverer with SQL? You may need to use a tool like TOAD to see it.
    Also, is Discoverer doing anything complicated with the data after it comes back? By complicated I mean do you have a large number of Page Items and / or Group Sorted items? SQL wouldn't have this overhead you see.
    Because SQL would create a table, have you tried creating a table in Discoverer and seeing how long it takes?
    Finally, what version of the database are you using?
    Issue 2:
    Your initial statement was that query rewrite works with several MV but not with others, yet in the body of the report you only show explain plans that do use the MV. Could you therefore go into some more detail regarding this situation.
    Best wishes
    Michael

  • Oracle Query Rewrite Alias Problem

    Hi,
    The problem desribed below is regarding the use of oracle aggregate awareness through the use of query rewrite.
    2 materialized views exist (one agg per day, one agg per month) and 1 dimension exists for time (date - month - quarter - year)
    Query rewrite seems to be working fine for a query as such (alias sql = alias mv):
    select DDFPC.MONTH_NO
    from BIDATA_MAIN.DF_REPOSITORY_SUBSET DF2, BIDATA_MAIN.DD_TIME DDFPC
    where DF2.FINANCIAL_PROCCESSING_DATE_ID = DDFPC.DATE_ID and DF2.ROUTING_CODE_ISS IN ('FPC','NCC')
    group by DDFPC.MONTH_NO
    However, considering our reporting tool generates aliases on the fly, we could get the following query (alias sql <> alias mv):
    select T2.MONTH_NO
    from BIDATA_MAIN.DF_REPOSITORY_SUBSET DF2, BIDATA_MAIN.DD_TIME T2
    where DF2.FINANCIAL_PROCCESSING_DATE_ID = T2.DATE_ID and DF2.ROUTING_CODE_ISS IN ('FPC','NCC')
    group by T2.MONTH_NO
    --> for the second query, query rewrite refuses to correctly use the dimension – it’ll rewrite to the DD (daily) aggregate, but not to the MM (monthly) aggregate
    Investigation gives: QSM-01072: materialized view, DA_REPOSITORY_MERCHANT_MM, and query have different joins between tables, DF_REPOSITORY_SUBSET and DD_TIME
    So*: How can query rewrite be forced to take place with different aliases between query & materialized view – taken into account a dimension is used for aggregation-awareness?
    This seems to indicate it should work...

    You are missing a join on the file_id column
    i.e.
    select sum(f.BLOCKS), sum(d.BLOCKS) from dba_free_space f ,dba_data_files d where f.TABLESPACE_NAME=d.TABLESPACE_NAME and f.TABLESPACE_NAME like SUBSTR('KU_TSD_1',0,10)
    and f.file_id = d.file_id
    This might have been easier to detect if you had removed the sum aggregation and looked at the data coming back from the raw query.

  • Usage of Query Rewrite in Materialized Views

    Hi,
    I have a star schema with fact table and and dimensions tables.
    One of the dimension tables is time_dimension and I have created
    a materialized view(time_sales_mv) on it and the fact table. I
    have also created a dimension(time_dim) on the
    table 'time_dimension' with hierarchies and attributes.
    Following are the syntaxes -
    --Dimension table
    CREATE TABLE TIME_DIMENSION (
    TIME_KEY NUMBER(9) NOT NULL,
    DAY_OF_MONTH NUMBER(9),
    WEEKDAY NUMBER(9),
    WEEKEND NUMBER(9),
    JULIAN_DAY NUMBER(9),
    JULIAN_WEEK NUMBER(9),
    JULIAN_YEAR NUMBER(9),
    MONTH_NUMBER NUMBER(9),
    MONTH_NAME VARCHAR2(15),
    WEEK_OF_THE_YEAR NUMBER(9),
    WEEKDAY_NAME VARCHAR2(10),
    WEEK_DAY_NUMBER NUMBER(9),
    THE_YEAR NUMBER(9),
    DAY_OF_THE_YEAR NUMBER(9),
    THE_DATE DATE,
    THE_QUARTER NUMBER(9),
    PRIMARY KEY ( TIME_KEY )) ;
    --Fact table
    CREATE TABLE SALES_FACT (
    TIME_KEY NUMBER(9) NOT NULL,
    PRODUCT_KEY NUMBER(9) NOT NULL,
    PROMOTION_KEY NUMBER(9) NOT NULL,
    CUSTOMER_KEY NUMBER(9) NOT NULL,
    DOLLAR_SALES FLOAT,
    UNIT_SALES NUMBER(9),
    DOLLAR_COST FLOAT)
    -- Dimension created
    CREATE DIMENSION Time_dim
    LEVEL THE_DATE IS TIME_DIMENSION.THE_DATE
    LEVEL WEEK_OF_THE_YEAR IS time_dimension.WEEK_OF_THE_YEAR
    LEVEL MONTH_NUMBER IS time_dimension.MONTH_NUMBER
    LEVEL THE_QUARTER IS time_dimension.THE_QUARTER
    LEVEL THE_YEAR IS time_dimension.THE_YEAR
    HIERARCHY calendar_rollup (
         THE_DATE CHILD OF
         MONTH_NUMBER CHILD OF
         THE_QUARTER CHILD OF
         THE_YEAR )
    HIERARCHY weekly_rollup (
         THE_DATE CHILD OF
    WEEK_OF_THE_YEAR )
    ATTRIBUTE THE_DATE DETERMINES
    time_dimension_sagar.DAY_OF_MONTH
    ATTRIBUTE THE_DATE DETERMINES
    time_dimension_sagar.WEEKDAY
    ATTRIBUTE THE_DATE DETERMINES
    time_dimension_sagar.JULIAN_DAY
    ATTRIBUTE THE_DATE DETERMINES
    time_dimension_sagar.DAY_OF_THE_YEAR
    ATTRIBUTE MONTH_NUMBER DETERMINES
    time_dimension_sagar.month_name
    ATTRIBUTE THE_YEAR DETERMINES
    time_dimension_sagar.JULIAN_YEAR;
    -- Materialized View
    CREATE MATERIALIZED VIEW time_sales_mv
    BUILD IMMEDIATE
    REFRESH COMPLETE ON DEMAND
    ENABLE QUERY REWRITE
    AS
    SELECT t.month_number, SUM
    (dollar_sales) AS sum_dollar_sales
    FROM sales_fact s,time_dimension t
    WHERE t.time_key =
    s.time_key GROUP BY
    t.month_number
    Now if I use the same query as in the MV and see the explain
    plan it shows the MV is being used instead of the underlying
    tables which is as expected. But if I change 'month_number'
    to 'month_name' in the above query, the explain plan does not
    use the MV which is not as expected. Since 'month_name' is an
    attribute of 'month_number'(defined in the dimension
    definition), we can use it and query rewrite feature will join
    the MV to the time_dimension table. But in the actual plan, it
    uses the fact table 'sales_fact' instead of the MV. Even when I
    use the rewrite hint on the query it does not use the MV. I want
    know why this is happening??
    Query-
    SELECT t.month_number, SUM(dollar_sales) AS
    sum_dollar_sales FROM
    sales_fact s, time_dimension t
    WHERE t.time_key = s.time_key
    GROUP BY t.month_number
    Explain Plan -
    SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=82 Bytes=2132)
    TABLE ACCESS (FULL) OF TIME_SALES_MV (Cost=1 Card=82
    Bytes=2132)
    Query(using month_name instead of month_number)-
    SELECT t.month_name, SUM(dollar_sales)
    FROM sales_fact s, time_dimension t
    WHERE t.time_key = s.time_key
    GROUP BY t.month_name
    Explain Plan -
    SELECT STATEMENT Optimizer=CHOOSE (Cost=151 Card=9053
    Bytes=307802)
    SORT (GROUP BY) (Cost=151 Card=9053 Bytes=307802)
    HASH JOIN (Cost=16 Card=9053 Bytes=307802)
    TABLE ACCESS (FULL) OF TIME_DIMENSION_SAGAR (Cost=1
    Card=82 Bytes=1804)
    TABLE ACCESS (FULL) OF SALES_FACT (Cost=10 Card=11040
    Bytes=132480)
    Query (using rewrite hint in the above query) -
    SELECT /*+ rewrite(time_sales_mv)*/
    t.month_name, SUM
    (dollar_sales)
    FROM sales_fact s, time_dimension t
    WHERE t.time_key = s.time_key
    GROUP BY t.month_name
    Explain Plan -
    SELECT STATEMENT Optimizer=CHOOSE (Cost=151 Card=9053
    Bytes=307802)
    SORT (GROUP BY) (Cost=151 Card=9053 Bytes=307802)
    HASH JOIN (Cost=16 Card=9053 Bytes=307802)
    TABLE ACCESS (FULL) OF TIME_DIMENSION_SAGAR (Cost=1
    Card=82 Bytes=1804)
    TABLE ACCESS (FULL) OF SALES_FACT (Cost=10 Card=11040
    Bytes=132480)

    Hi,
    I have a star schema with fact table and and dimensions tables.
    One of the dimension tables is time_dimension and I have created
    a materialized view(time_sales_mv) on it and the fact table. I
    have also created a dimension(time_dim) on the
    table 'time_dimension' with hierarchies and attributes.
    Following are the syntaxes -
    --Dimension table
    CREATE TABLE TIME_DIMENSION (
    TIME_KEY NUMBER(9) NOT NULL,
    DAY_OF_MONTH NUMBER(9),
    WEEKDAY NUMBER(9),
    WEEKEND NUMBER(9),
    JULIAN_DAY NUMBER(9),
    JULIAN_WEEK NUMBER(9),
    JULIAN_YEAR NUMBER(9),
    MONTH_NUMBER NUMBER(9),
    MONTH_NAME VARCHAR2(15),
    WEEK_OF_THE_YEAR NUMBER(9),
    WEEKDAY_NAME VARCHAR2(10),
    WEEK_DAY_NUMBER NUMBER(9),
    THE_YEAR NUMBER(9),
    DAY_OF_THE_YEAR NUMBER(9),
    THE_DATE DATE,
    THE_QUARTER NUMBER(9),
    PRIMARY KEY ( TIME_KEY )) ;
    --Fact table
    CREATE TABLE SALES_FACT (
    TIME_KEY NUMBER(9) NOT NULL,
    PRODUCT_KEY NUMBER(9) NOT NULL,
    PROMOTION_KEY NUMBER(9) NOT NULL,
    CUSTOMER_KEY NUMBER(9) NOT NULL,
    DOLLAR_SALES FLOAT,
    UNIT_SALES NUMBER(9),
    DOLLAR_COST FLOAT)
    -- Dimension created
    CREATE DIMENSION Time_dim
    LEVEL THE_DATE IS TIME_DIMENSION.THE_DATE
    LEVEL WEEK_OF_THE_YEAR IS time_dimension.WEEK_OF_THE_YEAR
    LEVEL MONTH_NUMBER IS time_dimension.MONTH_NUMBER
    LEVEL THE_QUARTER IS time_dimension.THE_QUARTER
    LEVEL THE_YEAR IS time_dimension.THE_YEAR
    HIERARCHY calendar_rollup (
         THE_DATE CHILD OF
         MONTH_NUMBER CHILD OF
         THE_QUARTER CHILD OF
         THE_YEAR )
    HIERARCHY weekly_rollup (
         THE_DATE CHILD OF
    WEEK_OF_THE_YEAR )
    ATTRIBUTE THE_DATE DETERMINES
    time_dimension_sagar.DAY_OF_MONTH
    ATTRIBUTE THE_DATE DETERMINES
    time_dimension_sagar.WEEKDAY
    ATTRIBUTE THE_DATE DETERMINES
    time_dimension_sagar.JULIAN_DAY
    ATTRIBUTE THE_DATE DETERMINES
    time_dimension_sagar.DAY_OF_THE_YEAR
    ATTRIBUTE MONTH_NUMBER DETERMINES
    time_dimension_sagar.month_name
    ATTRIBUTE THE_YEAR DETERMINES
    time_dimension_sagar.JULIAN_YEAR;
    -- Materialized View
    CREATE MATERIALIZED VIEW time_sales_mv
    BUILD IMMEDIATE
    REFRESH COMPLETE ON DEMAND
    ENABLE QUERY REWRITE
    AS
    SELECT t.month_number, SUM
    (dollar_sales) AS sum_dollar_sales
    FROM sales_fact s,time_dimension t
    WHERE t.time_key =
    s.time_key GROUP BY
    t.month_number
    Now if I use the same query as in the MV and see the explain
    plan it shows the MV is being used instead of the underlying
    tables which is as expected. But if I change 'month_number'
    to 'month_name' in the above query, the explain plan does not
    use the MV which is not as expected. Since 'month_name' is an
    attribute of 'month_number'(defined in the dimension
    definition), we can use it and query rewrite feature will join
    the MV to the time_dimension table. But in the actual plan, it
    uses the fact table 'sales_fact' instead of the MV. Even when I
    use the rewrite hint on the query it does not use the MV. I want
    know why this is happening??
    Query-
    SELECT t.month_number, SUM(dollar_sales) AS
    sum_dollar_sales FROM
    sales_fact s, time_dimension t
    WHERE t.time_key = s.time_key
    GROUP BY t.month_number
    Explain Plan -
    SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=82 Bytes=2132)
    TABLE ACCESS (FULL) OF TIME_SALES_MV (Cost=1 Card=82
    Bytes=2132)
    Query(using month_name instead of month_number)-
    SELECT t.month_name, SUM(dollar_sales)
    FROM sales_fact s, time_dimension t
    WHERE t.time_key = s.time_key
    GROUP BY t.month_name
    Explain Plan -
    SELECT STATEMENT Optimizer=CHOOSE (Cost=151 Card=9053
    Bytes=307802)
    SORT (GROUP BY) (Cost=151 Card=9053 Bytes=307802)
    HASH JOIN (Cost=16 Card=9053 Bytes=307802)
    TABLE ACCESS (FULL) OF TIME_DIMENSION_SAGAR (Cost=1
    Card=82 Bytes=1804)
    TABLE ACCESS (FULL) OF SALES_FACT (Cost=10 Card=11040
    Bytes=132480)
    Query (using rewrite hint in the above query) -
    SELECT /*+ rewrite(time_sales_mv)*/
    t.month_name, SUM
    (dollar_sales)
    FROM sales_fact s, time_dimension t
    WHERE t.time_key = s.time_key
    GROUP BY t.month_name
    Explain Plan -
    SELECT STATEMENT Optimizer=CHOOSE (Cost=151 Card=9053
    Bytes=307802)
    SORT (GROUP BY) (Cost=151 Card=9053 Bytes=307802)
    HASH JOIN (Cost=16 Card=9053 Bytes=307802)
    TABLE ACCESS (FULL) OF TIME_DIMENSION_SAGAR (Cost=1
    Card=82 Bytes=1804)
    TABLE ACCESS (FULL) OF SALES_FACT (Cost=10 Card=11040
    Bytes=132480)

  • 11g OLAP cube MV's   with Query Rewrite option

    Hi All,
    I am trying to test the 11g OLAP cube MV's with the Query Rewrite option.
    I had created a cube on the schema OLAPTRAIN problem by oracle. I an selected necessary options in 'Materialized Views' tab of the Cube definition in AWM. here is the screenshot
    !http://i40.tinypic.com/9jzpte.png!
    and then I try to run the SQL query
    select SUM(S.QUANTITY) AS QUAN,
    SUM(S.SALES) AS SALES,
    T.CALENDAR_YEAR_NAME,
    P.DEPARTMENT_NAME,
    C.COUNTRY_NAME
    FROM
    TIMES T,CUSTOMERS C,PRODUCTS P, SALES_FACT S
    WHERE
    C.CUSTOMER_KEY = S.CUSTOMER AND
    T.DAY_KEY = S.DAY_KEY AND
    P.ITEM_KEY = S.PRODUCT
    group by T.CALENDAR_YEAR_NAME, P.DEPARTMENT_NAME, C.COUNTRY_NAME;
    and observed the Explain plan, it is not using OLAP cube built, instead it is using the relational tables given in the above sql query.
    Also, i have observed that , though enabling or disabling of the Query Rewrite option doesn't make any change in the Explain query for the above query.
    alter materialized view olaptrain.cb$sales_cube enable query rewrite;
    alter materialized view OLAPTRAIN.cb$sales_cube disable query rewrite;
    No idea why is this Query Rewrite feature is not working on my Database instance of 11g R2 . Do am I missing any steps that has be taken care of , to make this working. Any inputs would be appreciated.
    Thanks
    S

    Hi there,
    You should check out Note 577293.1 on Metalink - 'Oracle OLAP 11g: How to ensure use of Cube Materialized Views/Query Rewrite'
    Thanks,
    Stuart Bunby
    OLAP Blog: http://oracleOLAP.blogspot.com
    OLAP Wiki: http://wiki.oracle.com/page/Oracle+OLAP+Option
    OLAP on OTN: http://www.oracle.com/technology/products/bi/olap/index.html
    DW on OTN : http://www.oracle.com/technology/products/bi/db/11g/index.html

  • No query rewrite

    i have a problem with query rewrite in 10gR1.
    create table time_hierarchy (
    day date primary key,
    mmyyyy char(6) not null,
    qyyyy char(5) not null,
    yyyy char(4) not null
    ) organization index;
    create table tx (
    shopid number not null,
    txdate date references time_hierarchy initially deferred
    not null,
    amount number not null
    create dimension tx_dimension
    level day is time_hierarchy.day
    level mmyyyy is time_hierarchy.mmyyyy
    level qyyyy is time_hierarchy.qyyyy
    level yyyy is time_hierarchy.yyyy
    hierarchy time_rollup (
    day child of
    mmyyyy child of
    qyyyy child of
    yyyy
    create materialized view tx_mv
    build immediate
    refresh on demand
    enable query rewrite
    as
    select a.shopid shopid,
    count(*) txnum,
    sum(a.amount) amountsum,
    b.mmyyyy mmyyyy
    from tx a join time_hierarchy b on a.txdate = b.day
    group by a.shopid, b.mmyyyy;
    i populated the tables and did a complete analyze.
    this query was rewritten:
    select /*+ REWRITE */ a.shopid shopid,
    b.mmyyyy mmyyyy,
    count(*) txnum,
    sum(a.amount) amountsum
    from tx a join time_hierarchy b on a.txdate = b.day
    group by a.shopid, b.mmyyyy
    order by a.shopid, b.mmyyyy;
    but this not:
    select /*+ REWRITE */ a.shopid shopid,
    b.qyyyy qyyyy,
    count(*) txnum,
    sum(a.amount) amountsum
    from tx a join time_hierarchy b on a.txdate = b.day
    group by a.shopid, b.qyyyy
    order by a.shopid, b.qyyyy;
    an explain_mview gave me this;
    MESSAGE
    QSM-01082: Joining materialized view, TX_MV, with table, TIME_HIERARCHY, not pos
    sible
    QSM-01102: materialized view, TX_MV, requires join back to table, TX, on column,
    AMOUNT
    QSM-01102: materialized view, TX_MV, requires join back to table, TX, on column,
    TXDATE
    QSM-01102: materialized view, TX_MV, requires join back to table, TIME_HIERARCHY
    , on column, YYYY
    MESSAGE
    QSM-01102: materialized view, TX_MV, requires join back to table, TIME_HIERARCHY
    , on column, QYYYY
    QSM-01102: materialized view, TX_MV, requires join back to table, TIME_HIERARCHY
    , on column, DAY
    QSM-01086: dimension(s) not present or not used in ENFORCED integrity mode
    QSM-01063: query has a dictionary table or view
    if i set integrity to trusted, the latter query will be rewritten too.
    can anyone explain me why? i'm clueless.
    Best,
    -ap

    yes, see definition of tx, relation tx.txdate->time_hierarchy.day
    what puzzles me is the fact, that mmyyyy works but not qyyyy.
    both are levels of day.
    -j

Maybe you are looking for

  • Firefox won't run: XULRunner - Error: Platform version 5.0 is not compatible with miniVersion = 5.0.1 maxVersion =5.0.1

    Got this error. Tried to download and reinstall latest version. Said that it installed/upgraded ok. Tried to run again and got same crash.

  • Connect my macbook to my LCD TV

    Does somebody knows what cable i have to buy if i want to connect my Mac-screen to my LCD TV? On this way is it also possible to listen the music on my tv? Thanks a lot for your answers..

  • Compressed videos not playing in IPAD

    Hi, I am using flash professional cs6 .my project is depends upon Multimedia.mainly my Application for iPad.   I am using some videos which are in .flv . Those flv files are too large so that i compressed all videos and loaded into my application.Aft

  • 20" ACD seems dim?

    I have a 20" Apple Cinema Display that seems like it's losing it brightness. The display is used everyday and is about 5 years old. How can I tell if the brightness is normal or has faded?

  • Can't delete Maps 'Recents' or save 'Bookmarks!

    As title really - I have a new iPhone 4 restored with backup from my 3G. I can't delete Maps 'Recents' or save 'Bookmarks'. If I clear 'Recents', they go away but reappear sometime over the next day or so. Also, I can save Bookmarks, but they've vani