Views defined with SELECT * impose their cost on every reader
A view that selects every column makes column pruning impossible for anyone querying it — even someone selecting a single field.
What it is
A logical view is expanded into the query that references it. If the view says SELECT *, the expansion reads every column of the underlying table, and a consumer selecting one column can still be billed for all of them depending on how the expansion optimises.
Why it costs money
- The cost is invisible at the call site. The consumer's SQL looks minimal and cheap.
- Views are shared, so one careless definition multiplies across every team using it.
- Nested views compound the problem, and nobody reads three levels of definitions before writing a query.
Worked example
Expensive
CREATE VIEW `analytics.v_events` AS
SELECT * FROM `analytics.events_raw`Cheaper
CREATE VIEW `analytics.v_events` AS
SELECT event_id, user_id, event_name, event_timestamp, event_date
FROM `analytics.events_raw`The arithmetic. A consumer running SELECT user_id FROM v_events against a 2 TiB table can be billed for far more than the ~8 GiB that column occupies.
How to fix it
- 1Enumerate columns in view definitions, exactly as in queries.
- 2Audit view definitions with INFORMATION_SCHEMA.VIEWS and grep for SELECT *.
- 3Prefer authorized views with an explicit column list where the view exists for access control.
No single query reveals this one. It shows up across job history instead — the query pack has recipes that find it.
Fixing one query is satisfying. Fixing the pattern is the win.
Finitizer finds every instance of this across your BigQuery job history, ranks them by what they actually cost, and keeps checking after you have fixed them.