The New Home of Oracle-wiki.net

All things oracle...

A website for IT Professionals involved with Oracle database.

LinkLinkedIn

REWRITE and NO_REWRITE Hint

Introduction

Oracle's REWRITE hint forces the optimizer to consider rewriting a specific SQL query to use a materialized view, instead of the underlying base tables.  Specifically, it tells the optimizer to use materialized views where possible.  The idea is to boost performance by using pre-calculated results of the MV. 

Example

SELECT /*+ REWRITE */ col1 

  FROM myTab1

  WHERE myTab1.col1= 100

/


OR


SELECT /*+ REWRITE(myMv1, myMv2) */ col1 

  FROM myTab1

  WHERE myTab1.col1= 100

/


You can specify a list of materialized view names within the hint  as shown above e.g. /*+ REWRITE(mv1, mv2) */. This limits the scope of the optimizer's search to only those listed MV's. If you omit the list of MV's, then the optimizer will consider all eligible materialized views. 


Important Notes


Detailed Example

You have a large sales table  on which you frequently run aggregate queries to get the total sales per region. To optimize performance, you create a materialized view that pre-aggregates the data. See below.


CREATE MATERIALIZED VIEW sales_mv

BUILD IMMEDIATE

REFRESH COMPLETE

ENABLE QUERY REWRITE AS

SELECT region, SUM(amount) AS total_sales

FROM sales

GROUP BY region

/


Selecting data from this table with the initialization parameter QUERY_REWRITE_ENABLED set to false, means the query will not be re-written


SELECT region, SUM(amount)

FROM sales

GROUP BY region

/


Assuming, no indexes on the sales table you would a plan similar to the following


------------------------------------------------------------------------------------

| Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time             |

------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |       |  1000 | 10000 |   50  (10) | 00:00:01         |

|   1 |  HASH GROUP BY     |       |  1000 | 10000 |   50  (10) | 00:00:01         |

|   2 |   TABLE ACCESS FULL| SALES | 10000 | 100K  |   40  (15) | 00:00:02         |

------------------------------------------------------------------------------------


If you were to run the query with the hint


SELECT /*+ REWRITE(sales_mv) */ region, SUM(amount)

FROM sales

GROUP BY region

/


then the query plan would look something like this

------------------------------------------------------------------------------------

| Id  | Operation            | Name               | Rows  | Bytes | Cost (%CPU)    |

------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT     |                    |  1000 | 10000 |    5  (1)      |

|   1 |  INDEX FULL SCAN     | IDX_SALES_MV_REGION|  1000 | 10000 |    5  (1)      |

------------------------------------------------------------------------------------


Obviously, this query with and without the hint, could be improved with standard indexing too, but the principle of how the optimizer re-writes the query is shown in the plan above,.


Note

The NO_REWRITE hint instructs the optimizer to disable query rewrite for the query block, overriding the setting of the initialization  parameter QUERY_REWRITE_ENABLED = TRUE


Example

SELECT /*+ NO_REWRITE */ col1 

  FROM myTab1

  WHERE myTab1.col1= 100

/


Further Reading

Published on 

Published 14th February 2025