Which queries are scanning partitioned tables without a partition filter?
Find the queries that read every partition of a partitioned table — usually the single largest avoidable cost in a BigQuery estate.
Free to run — INFORMATION_SCHEMA scans no billable bytesChecked 4 Aug 2026
This recipe reads both region-scoped and dataset-scoped views, so it needs both.
-- Queries that touched a partitioned table but billed a suspiciously
-- large fraction of it. Heuristic: bytes billed within 20% of the table's
-- total logical size means little or no pruning happened.
WITH partitioned AS (
SELECT DISTINCT table_schema, table_name
FROM `my-project.my_dataset`.INFORMATION_SCHEMA.COLUMNS
WHERE is_partitioning_column = 'YES'
),
sizes AS (
SELECT table_schema, table_name, total_logical_bytes
FROM `region-us`.INFORMATION_SCHEMA.TABLE_STORAGE
),
jobs AS (
SELECT
job_id, user_email, creation_time, total_bytes_billed,
ref.dataset_id AS table_schema,
ref.table_id AS table_name,
SUBSTR(REGEXP_REPLACE(query, r'\s+', ' '), 0, 300) AS query_preview
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT,
UNNEST(referenced_tables) AS ref
WHERE creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
AND job_type = 'QUERY'
AND state = 'DONE'
AND error_result IS NULL
)
SELECT
j.job_id, j.user_email, j.table_schema, j.table_name,
j.total_bytes_billed,
s.total_logical_bytes,
ROUND(SAFE_DIVIDE(j.total_bytes_billed, s.total_logical_bytes), 3) AS fraction_of_table,
j.query_preview
FROM jobs j
JOIN partitioned p USING (table_schema, table_name)
JOIN sizes s USING (table_schema, table_name)
WHERE SAFE_DIVIDE(j.total_bytes_billed, s.total_logical_bytes) > 0.8
ORDER BY j.total_bytes_billed DESC
LIMIT 50;What it returns
- fraction_of_table
- Bytes billed ÷ the table's total logical size. Near 1.0 means a full scan.
- total_logical_bytes
- The whole table, uncompressed — the denominator.
How to read it
- The ratio is a heuristic, not proof. A query selecting every column of every partition scores ~1.0; so does one selecting one column across a table where that column is most of the bytes. Read the query preview before filing a ticket.
- The fix is almost never "add a WHERE clause" in isolation — it is to set require_partition_filter on the table so the next person cannot make the same mistake.
- Ratios above 1.0 happen and are not a bug: a self-join reads the table twice.
Take it further
Run this once, or have it run every day.
Finitizer evaluates this class of question continuously against your live BigQuery estate, tracks how each number moves between runs, and turns findings into assigned tasks. Read-only and keyless.