title: Materialized View fast refresh taking a long time
body: <p>I have a large table that is replicated from Oracle 10.2.0.4 to and Oracle 9i database using MView replication over the network.  The master table is about 50GB, 160M rows and there are about 2 - 3M new or updates rows per day.</p>
  
  <p>The master table has a materialized view log created using rowid.</p>
  
  <p>The full refresh of the view works and takes about 5 hours, which we can live with.</p>
  
  <p>However the fast refresh is struggling to keep up.  Oracle seems to require two queries against the mlog and master table to do the refresh, the first looks like this:</p>
  
  <pre><code>SELECT          /*+ */
     DISTINCT "A1"."M_ROW$$"
         FROM "GENEVA_ADMIN"."MLOG$_BILLSUMMARY" "A1"
        WHERE "A1"."M_ROW$$" &lt;&gt; ALL (SELECT "A2".ROWID
                                       FROM "GENEVA_ADMIN"."BILLSUMMARY" "A2"
                                      WHERE "A2".ROWID = "A1"."M_ROW$$")
          AND "A1"."SNAPTIME$$" &gt; :1
          AND "A1"."DMLTYPE$$" &lt;&gt; 'I'
  </code></pre>
  
  <p>The current plan is:</p>
  
  <pre><code>---------------------------------------------------------------
  | Id  | Operation                     | Name                  |
  ---------------------------------------------------------------
  |   0 | SELECT STATEMENT              |                       |
  |   1 |  HASH UNIQUE                  |                       |
  |   2 |   FILTER                      |                       |
  |   3 |    TABLE ACCESS BY INDEX ROWID| MLOG$_BILLSUMMARY     |
  |   4 |     INDEX RANGE SCAN          | MLOG$_BILLSUMMARY_AK1 |
  |   5 |    TABLE ACCESS BY USER ROWID | BILLSUMMARY           |
  </code></pre>
  
  <p>When there are 3M rows changed, this query literally runs forever - its basically useless.  However, if I rewrite it slightly and tell it to full scan the master table and mlog table, it completes in 20 minutes.</p>
  
  <p>The problem is that the above query is coming out of the inners of Oracle and I cannot change it.  The problem is really the FILTER operation on line 2 - if I could get it to full scan both tables and hash join / anti-join, I am confident I can get it to complete quick enough, but no receipe of hints I offer will get this query to stop using the FILTER operation - maybe its not even valid.  I can use hints to get it to full scan both the tables, but the FILTER operation remains, and I understand it execute long 5 for each row returned by line 3, which will be 2- 3M rows.</p>
  
  <p>Has anyone got any ideas on how to trick this query into the plan I want without changing the actual query, or better, any ways of getting replication to take a more sensible plan for my tablesizes?</p>
  
  <p>Thanks,</p>
  
  <p>Stephen. </p>