Chinmay Kolhatkar - Vendor
08/03/2026, 12:25 PMRocky
08/03/2026, 12:26 PMidentity, year, month, day, or hour).
* Not "Only" Dirty Refresh: While partition-level refresh is the efficient "incremental" method for Iceberg, it is not the only support. StarRocks also supports:
* Full Refresh: If the MV is not partitioned or if you manually trigger a refresh with the FORCE keyword, StarRocks will perform a full-size refresh.
* Refresh Modes: You can set the refresh_mode property to INCREMENTAL to ensure it attempts partition-level updates.
In summary, for MVs on Iceberg, "incremental" refresh is specifically partition-based. StarRocks does not currently support row-level incremental updates (like CDC/Binlog) for external Iceberg tables; if a single row changes in a partition, the entire "dirty" partition is recalculated.
References
• using_starrocks/async_mv/use_cases/data_lake_query_acceleration_with_materialized_views.md
• sql-reference/sql-statements/materialized_view/CREATE_MATERIALIZED_VIEW.md
• using_starrocks/async_mv/use_cases/create_partitioned_materialized_view.mdChinmay Kolhatkar - Vendor
08/03/2026, 12:30 PMRocky
08/03/2026, 12:30 PMsql
-- Existing Iceberg Table in a catalog named 'iceberg_catalog'
CREATE TABLE iceberg_catalog.db.orders (
order_id BIGINT,
customer_id INT,
order_date TIMESTAMP,
amount DECIMAL(10, 2)
)
PARTITIONED BY (days(order_date));
2. Materialized View with Incremental Refresh
To refresh only changed partitions, use PARTITION BY with the matching partition expression and set the refresh_mode to INCREMENTAL.
sql
CREATE MATERIALIZED VIEW mv_iceberg_daily
-- 1. Align the partition with the base Iceberg table
PARTITION BY date_trunc('day', order_date)
-- 2. Define the refresh strategy (can be ASYNC or MANUAL)
REFRESH ASYNC EVERY (INTERVAL 1 HOUR)
PROPERTIES (
-- 3. Only refresh partitions that have changed (dirty)
"refresh_mode" = "INCREMENTAL",
-- Optional: Limit the number of dirty partitions refreshed in one batch
"partition_refresh_number" = "10"
)
AS
SELECT
order_date,
customer_id,
SUM(amount) as daily_revenue
FROM iceberg_catalog.db.orders
GROUP BY order_date, customer_id;
Key Requirements for "Dirty" Refresh to Work:
* Partition Alignment: The MV's PARTITION BY column must be included in the base table's partition columns. Since Iceberg uses transforms, you must map them correctly (e.g., Iceberg days(col) maps to StarRocks date_trunc('day', col)).
* refresh_mode: Setting this to INCREMENTAL tells StarRocks to only recalculate partitions where the underlying Iceberg snapshot metadata indicates a change.
* Metadata Detection: StarRocks (v3.1.4+) automatically tracks Iceberg snapshot IDs. When a refresh occurs, it identifies which partitions have new data and refreshes only those.
How to trigger manually for only dirty partitions:
If you want to manually trigger the refresh of just the dirty partitions:
sql
REFRESH MATERIALIZED VIEW mv_iceberg_daily;
(StarRocks will check the metadata and only process the changed partitions.)
References
• using_starrocks/async_mv/use_cases/data_lake_query_acceleration_with_materialized_views.md
• sql-reference/sql-statements/materialized_view/CREATE_MATERIALIZED_VIEW.md
• using_starrocks/async_mv/use_cases/create_partitioned_materialized_view.md
ized_view)
)
view)
References
• sql-reference/sql-statements/materialized_view/CREATE_MATERIALIZED_VIEW.md
• using_starrocks/async_mv/use_cases/create_partitioned_materialized_view.md