Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Materialized View Odd Behavior

I have a source table that's pretty large. It's partitioned by day but has no cluster on it for now.

I have a bunch of materialized views that just select from this source table and filter on a specific region. The materialized view definition itself didn't have a partition filter, so any queries using the mvs needed to have this added to them.

I found that each of these materialized views, even when adding date filters, were still scanning the entire table since the rendered processed bytes for even selecting 1 day from the materialized view was as read-intensive as selecting from the entire base table.

Now, this source table only goes back to 2020-01-01 (that is the absolute min date on the table). I found that, oddly enough, if I added a filter to the materialized view directly by saying where date >= '2020-01-01', the read for the query was dropping hundreds if not terabytes of read even though this filter effectively does not exclude any data whatsoever since that is the minimum date anyways.

After implementing this, we're saving a ridiculous amount of read (and therefore money) for something that we can really not explain so well. Can anyone explain this?

Solved Solved
2 4 1,899
1 ACCEPTED SOLUTION

When you add a filter to a materialized view in BigQuery, the system uses this filter as a hint or context to optimize data scanning. This is achieved through techniques like predicate pushdown, where BigQuery tries to apply filters as early as possible in the data retrieval process.

The reason you observe performance improvements even with a seemingly broad filter is due to BigQuery's logical optimization techniques. By providing a filter in the materialized view definition, you give BigQuery a context about the data's structure, allowing it to make more efficient decisions about which partitions or clusters to scan.

In your case, without the filter, querying the materialized view might result in scanning a large portion of the data, say 450 GB. However, with the filter in place, even if it doesn't technically exclude much data, BigQuery can optimize the scan, leading to a much smaller amount of data being processed, like 3 GB. This optimization results in a significant performance boost.

View solution in original post

4 REPLIES 4

Your response is mostly accurate, but there are a few points that need clarification or correction:

Physical Copy in Materialized Views: While it's true that a materialized view stores a "copy" of the data, it's not an exact replica of the base table. Instead, it's a precomputed result set based on the SQL query used to define the materialized view. This precomputed result is what makes querying materialized views faster.

Predicate Pushdown: Your explanation of predicate pushdown is correct. However, it's important to note that predicate pushdown is a general optimization technique used in many database systems, not just BigQuery. In the context of BigQuery and materialized views, the benefit of predicate pushdown is more pronounced when the materialized view itself has filters (like the date filter you mentioned).

Clustering: Clustering is a technique that organizes data by specific columns to optimize query performance, not necessarily by partition. While partitioning divides a table into segments based on a specific column's range of values, clustering sorts data within each partition based on the values in one or more columns. So, when you mention clustering by date, it's more accurate to say "cluster the materialized view by a column (e.g., region) to optimize queries that filter by that column."

max_staleness: This property is specific to BigQuery BI Engine and not general materialized views. It determines how long BigQuery BI Engine will use the materialized view data before considering it stale. It's not about refreshing the materialized view itself.

Materialized View as a Pseudo-Index: This is a good point. When a query is issued against the base table, BigQuery will automatically consider using the materialized view if it determines that doing so will be more efficient.

Here's a revised version of your response:

When you create a materialized view, BigQuery computes a result set based on the SQL query used to define the materialized view and stores it. This precomputed result set is what makes querying materialized views faster.

In your case, the materialized views were scanning the entire table even with a date filter because the filter was applied to the queries using the materialized view, not the view itself. By adding the where date >= '2020-01-01' filter to the materialized view, you provided a hint to BigQuery about the data range, optimizing the data scanned.

BigQuery uses a technique called predicate pushdown to optimize queries. This means filters applied to a query are pushed down to the data source. In this context, the date filter was applied to the materialized view, telling BigQuery to scan only the relevant data range.

Additional points:

To further optimize query performance, consider clustering the materialized view by a specific column (e.g., region) to speed up queries that filter by that column.
BigQuery automatically uses materialized views to optimize queries that match the view's definition, acting as a pseudo-index.

Thank you for the speedy reply! Was there another response here that got deleted? Some of these points I don't think I mentioned.

What I'm still struggling to understand is why adding the filter to the materialized view directly tells BigQuery that less data needs to be read, because it's reading the identical amount of data anyways since the source table's minimum date is '2020-01-01'. In fact, even if I put a ridiculous filter i.e. where date >= '1950-01-01' (where there certainly is no data yet), it still provides the same performance boost (from 450 GB processed to 3 GB processed). Excuse my ignorance but do you mind explaining how that seemingly arbitrary filter provides such a large optimization if it's technically reading the same amount of data anyways?

When you add a filter to a materialized view in BigQuery, the system uses this filter as a hint or context to optimize data scanning. This is achieved through techniques like predicate pushdown, where BigQuery tries to apply filters as early as possible in the data retrieval process.

The reason you observe performance improvements even with a seemingly broad filter is due to BigQuery's logical optimization techniques. By providing a filter in the materialized view definition, you give BigQuery a context about the data's structure, allowing it to make more efficient decisions about which partitions or clusters to scan.

In your case, without the filter, querying the materialized view might result in scanning a large portion of the data, say 450 GB. However, with the filter in place, even if it doesn't technically exclude much data, BigQuery can optimize the scan, leading to a much smaller amount of data being processed, like 3 GB. This optimization results in a significant performance boost.

Thanks, that answers my question. But I have a much bigger question which is that this only suddenly occurred. Overnight, on July 19th, the cost for these materialized views literally skyrocketed. Nothing in the source table changed whatsoever. Was some update made recently?