Forum Discussion
Can't make MLV refresh incrementally
- 6 months ago
Hi dragospopescu ,
Your MLV is doing too much.
Between:
Overwrite strategy
UNION ALL blocks
DISTINCT usage
Nested LEFT JOINs
Fabric's incremental engine has no safe way to compute deltas.So it correctly falls back to FullRefresh.
I would do the below changes
1. For bronze layer Instead of replacing 01.01.2026 with 01.02.2026 using mode("append") or MERGE INTO with additional column for ingestion date
2. Instead of distinct create proper dimension tables first and then use only the pre-processed tables in join that would be helpful.ALso remove union to IN
Split Silver Layer into Multiple MLVs
Instead of one heavy MLV:
Do:
Bronze
⬇
Silver_Base_MLV (no joins, no distinct, no unions)
⬇
Silver_Join_MLV (only joins)
⬇
Gold (aggregations if needed)
If business logic truly requires: "When February file arrives, January data must disappear completely"
Then incremental MLV is simply not appropriate. Because that is a batch replacement pattern, not incremental processing.
If this post helps, then please appreciate giving a Kudos or accepting as a Solution to help the other members find it more quickly.
If I misunderstand your needs or you still have problems on it, please feel free to let us know. Thanks a lot!
As you can imagine, I can't provide even a simplified version of the codes, but I did my best below in trying to show you how the structure looks like. I think this should help well enough in the context of this post.
Bronze tables
These are created in similar fashion, relying on PySpark for parametrization, dynamic logic for file ingestion, ETL and clean-up, and finally the writing of the tables which is done as below.
df.write.mode("overwrite").format("delta").option("delta.enableChangeDataFeed", "true").partitionBy("Key").saveAsTable(table_name)
The overwrite is there because the input files have timestamps, so if say you already have data from 01.01.2026, when you upload the file for 01.02.2026 you don't need the previous data anymore. Thus, you need to overwrite the existing data in the lakehouse.
Silver MLV
Below is the structure/skeleton for the MLV, as mentioned at the beginning.
sql_statement = f"""
CREATE OR REPLACE MATERIALIZED LAKE VIEW mlv_nane
TBLPROPERTIES (delta.enableChangeDataFeed=true)
AS
SELECT
columns
FROM (
SELECT columns FROM table WHERE conditions
UNION ALL
SELECT columns FROM table WHERE conditions
UNION ALL
SELECT columns FROM table WHERE conditions
UNION ALL
SELECT columns FROM table WHERE conditions
) AS base_table
LEFT JOIN (SELECT DISTINCT columns FROM table) AS join_1
ON base_table.id = join_1.id
LEFT JOIN (SELECT DISTINCT columns FROM table) AS join_2
ON base_table.id = join_2.id
LEFT JOIN (SELECT DISTINCT columns FROM table) AS join_3
ON base_table.id = join_3.id
LEFT JOIN (SELECT DISTINCT columns FROM table) AS join_4
ON base_table.id = join_4.id
LEFT JOIN (SELECT DISTINCT columns FROM table) AS join_5
ON base_table.id = join_5.id
"""
spark.sql(sql_statement)
Testing
In the notebook I created for testing, the logic is something like this:
from pyspark.sql import Row
mock_row = Row( columns and values )
mock_df = spark.createDataFrame([mock_row])
mock_df.write.format("delta").option("delta.enableChangeDataFeed", "true").mode("append").saveAsTable(table_name)
Note: table_name from Testing is the same table_name from the Bronze layer.
Hi dragospopescu ,
Your MLV is doing too much.
Between:
Overwrite strategy
UNION ALL blocks
DISTINCT usage
Nested LEFT JOINs
Fabric's incremental engine has no safe way to compute deltas.So it correctly falls back to FullRefresh.
I would do the below changes
1. For bronze layer Instead of replacing 01.01.2026 with 01.02.2026 using mode("append") or MERGE INTO with additional column for ingestion date
2. Instead of distinct create proper dimension tables first and then use only the pre-processed tables in join that would be helpful.ALso remove union to IN
Split Silver Layer into Multiple MLVs
Instead of one heavy MLV:
Do:
Bronze
⬇
Silver_Base_MLV (no joins, no distinct, no unions)
⬇
Silver_Join_MLV (only joins)
⬇
Gold (aggregations if needed)
If business logic truly requires: "When February file arrives, January data must disappear completely"
Then incremental MLV is simply not appropriate. Because that is a batch replacement pattern, not incremental processing.
If this post helps, then please appreciate giving a Kudos or accepting as a Solution to help the other members find it more quickly.
If I misunderstand your needs or you still have problems on it, please feel free to let us know. Thanks a lot!
- dragospopescu6 months agoAdvocate I
Thanks for your point of view. I will mark your answer as a solution because most likely it's a combination of over-engineering the MLV and the contradicting requests (incremental refresh, full replace of data).
Even though this will be a closed topic by accepting a solution, I will try my best to come back with the actual technical solution at some point, when I develop something that meets all needs.