SQL24 min readBy Priyanshu Pandey

SQL Masterclass: Materialized Views & Query Rewrite

Accelerate your data warehouse dashboards using Oracle Materialized Views. Learn about Fast Refresh, ON COMMIT refreshes, and how to configure Query Rewrite to intercept and speed up user queries automatically.

Performance Guide · SQL Masterclass

Materialized Views: Caching Aggregations for Speed

Don't compute the total sales across 500 million rows every time a user refreshes a dashboard. Learn how to persist aggregations to disk using Materialized Views, and how to update them instantly using Fast Refresh.

24 min read📅August 7, 2026✍️Priyanshu Pandey📚SQL Masterclass

The Recomputation Problem

Imagine you have a dashboard that shows the "Total Sales by Store for the Year." The underlying SQL query aggregates 2 billion rows from the TRAN_DATA table.

Every time a user opens the dashboard, the database performs a massive SUM() and GROUP BY operation, burning massive CPU and taking 45 seconds to load.

A Standard View won't help, because a standard view is just a macro for a SQL query—it still executes against the base tables every time.

A Materialized View (MView) solves this. It runs the query once, and actually creates a physical table on disk to store the results. When the user queries the MView, it returns instantly because the aggregation is already done!

Implementation

Creating a Materialized View

Creating an MView is as simple as defining a query and a refresh schedule.

SQL
CREATE MATERIALIZED VIEW mv_sales_by_store
BUILD IMMEDIATE
REFRESH COMPLETE ON DEMAND
AS
SELECT 
  store_id, 
  SUM(amount) as total_sales, 
  COUNT(*) as transaction_count
FROM sales
GROUP BY store_id;
  • BUILD IMMEDIATE: Populates the view right now.
  • REFRESH COMPLETE: When refreshed, it deletes all data and re-runs the full 2-billion-row query.
  • ON DEMAND: Only refreshes when a DBA explicitly calls DBMS_MVIEW.REFRESH.

Refresh Strategies (Complete vs Fast)

A Complete refresh of a massive table is agonizingly slow. If only 500 new sales occurred today, why recalculate the billions of historical sales?

Fast Refresh to the rescue.

A Fast Refresh uses a Materialized View Log on the base table. This log acts like a trigger, recording exactly which rows were inserted, updated, or deleted since the last refresh. When you trigger the refresh, Oracle only processes the delta (the 500 new sales) and adjusts the aggregates (e.g., adding to the SUM() and COUNT()).

Step 1: Create the MView Log

SQL
CREATE MATERIALIZED VIEW LOG ON sales 
WITH ROWID, SEQUENCE (store_id, amount) 
INCLUDING NEW VALUES;

Step 2: Create the Fast Refresh MView

SQL
CREATE MATERIALIZED VIEW mv_sales_by_store
BUILD IMMEDIATE
REFRESH FAST ON COMMIT -- Refreshes automatically every time a sale is committed!
AS
SELECT 
  store_id, 
  SUM(amount) as total_sales, 
  COUNT(*) as transaction_count
FROM sales
GROUP BY store_id;
⚠️

ON COMMIT Overhead

REFRESH FAST ON COMMIT means every transaction that modifies the base table must wait for the MView to update before the commit succeeds. In a high-throughput OLTP system, this causes massive contention. It is safer to use ON DEMAND and refresh it via a scheduled job every 5 minutes.

Optimizer Tricks

The Magic of Query Rewrite

You have built mv_sales_by_store. But your BI tool (like Tableau) doesn't know about it. The BI tool is hardcoded to query the base sales table. Do you have to rewrite all your reports?

No! Enable Query Rewrite.

SQL
ALTER MATERIALIZED VIEW mv_sales_by_store ENABLE QUERY REWRITE;

When a user executes:

SQL
SELECT store_id, SUM(amount) FROM sales GROUP BY store_id;

The Cost-Based Optimizer intercepts the query. It realizes, "Wait, this aggregation perfectly matches mv_sales_by_store!" It secretly rewrites the user's query behind the scenes to select from the MView instead. The BI tool gets the result instantly without changing a single line of its code.

Common Gotchas

Important Gotchas

  • !

    If the base table has been updated, but the MView has not been refreshed yet, the MView is considered "Stale". By default, the CBO will not rewrite queries to use a Stale MView (to ensure data accuracy). You can override this if your business tolerates slightly old data by using ALTER SESSION SET QUERY_REWRITE_INTEGRITY = STALE_TOLERATED;.

  • !

    You cannot use FAST REFRESH if your query contains certain complex operations like UNION, outer joins, or non-deterministic functions (like SYSDATE). Oracle will throw an error when you try to create it.

Key Takeaways

Key Takeaways

  • Materialized Views store the physical results of a query on disk, acting as pre-computed aggregation caches.
  • Use Materialized View Logs to enable FAST REFRESH, which dramatically reduces refresh times by only processing delta changes.
  • Enable Query Rewrite so the database optimizer can transparently redirect heavy user queries to your optimized MViews.
RetailCoder
All systems operational
v1.0 Live

RC:OMS

Multi-channel order management with double-entry inventory ledger. Amazon, Flipkart, Shopify, WooCommerce — one source of truth.

Launch demo →
v1.0 Live

RC:Storefront

Self-hosted headless e-commerce. Your server, your data, zero transaction fees. Native RC:OMS inventory sync.

Visit Storefront →
Pipeline

RC:Pulse

AI-powered retail analytics and demand forecasting — built natively on top of your RC:OMS and Storefront data.

Request early access →
Built in India 🇮🇳  ·  Architected by Priyanshu PandeyTalk to an engineer →