資料已經可以查了,SQL 也能正常執行。
但我開始注意到一件事情:
查詢可以成功,不代表這是一個好的查詢。
尤其在 BigQuery 裡,我不能只看 SQL 結果對不對。
還要開始問:
這次查詢到底掃了多少資料?
這個問題在 50 筆資料時幾乎沒有感覺,但如果今天不是 50 筆,而是幾 TB 的資料,答案就完全不同了。
以前看到查詢結果出現,我的第一反應是:
有結果,代表成功。
但 BigQuery 的查詢介面其實還提供另一個很重要的資訊:
這次查詢預計會處理多少資料。
這讓我的注意力開始從「結果是多少」轉向「得到這個結果花了多少資料處理量」。
假設未來這張表變成 1 TB,而我只是想看其中兩三個欄位,卻習慣把整張表的所有欄位都讀進來,那麼「方便」的寫法就可能變成大量不必要的資料處理。
Google Cloud 目前的最佳實務也明確建議控制查詢投影,也就是只讀取真正需要的欄位;因為讀取過多欄位會增加不必要的 I/O 與結果產生成本。
所以我現在不會把「不要一次拿全部欄位」理解成一條死規則。
我比較願意把它理解成:
如果只是探索資料,就探索;如果已經知道自己要回答什麼問題,就不要讓系統替我讀一堆用不到的東西。
這是我覺得很值得留下來的一個習慣。
以前我的流程是:
寫查詢 → 執行 → 看結果。
現在我會多加一個步驟:
寫完之後,先看這次查詢可能會處理多少資料。
因為如果等查詢執行完才發現資料量太大,事情已經發生了。
BigQuery 本身提供查詢執行資訊與 Query Plan,可以進一步查看不同階段處理了多少資料,以及哪些階段可能成為效能瓶頸。Google Cloud 目前也把「減少處理資料量」列為查詢最佳化的重要方向。
所以我開始把查詢前的估算,視為一種「預檢」。
就像開車前先看油量一樣。
不是因為車一定會沒油,而是先知道自己準備做什麼。
接下來我開始研究日期條件。
如果我只想看其中一週,當然可以把日期範圍縮小。
一開始我只是把這件事情理解成:我要的資料比較少,所以結果比較少。
但查完官方文件後,我發現這個理解其實不完整。
如果資料表本身有按照日期進行 Partition,那麼適當的日期條件不只是讓「結果變少」,而是可以讓 BigQuery 根本不需要掃描那些不符合條件的 Partition。
這就是 Partition Pruning。
Google Cloud 官方文件目前也明確指出,對分區表使用分區欄位進行篩選,可以限制實際被處理的 Partition,進而改善效能並降低處理成本。
這讓我開始重新理解 WHERE。
以前:
WHERE 是拿來找我要的資料。
現在:
好的 WHERE,也是在告訴系統哪些資料根本不用碰。
這個差別非常重要。
如果只是把資料按照月份、日期切開,我可能會把 Partition 理解成整理資料的工具。
但實際查詢後,我開始覺得它更像是一道「資料範圍的門」。
例如我要查某幾天的資料。
如果表本身按照日期分區,BigQuery 可以先判斷哪些區域完全不需要處理。
因此:
不需要的資料,不只是最後不顯示,而是有機會從一開始就不要讀。
Google Cloud 的文件也特別強調,Partitioning 的價值之一,就是降低查詢需要讀取的資料量。
這讓我開始理解為什麼資料表設計會影響後面的查詢成本。
接下來我碰到 Clustering。
一開始我很容易把它和 Partition 混在一起。
後來我用一個比較直覺的方式理解:
Partition 是先縮小大範圍。
Clustering 是在剩下的資料裡,再幫忙縮小範圍。
這次我用 region 作為 Clustering 的欄位。
因為如果未來的分析經常按照區域查詢,讓資料依照這類常用條件組織,就有機會讓 BigQuery 少掃描不相關的資料區塊。
Google Cloud 官方目前也建議,應根據實際查詢模式選擇 Partition 與 Clustering,而不是單純因為「這兩個功能很好」就全部套上去。
所以我現在不會問:
「這張表要不要 Partition?」
而會先問:
「未來最常怎麼查這張表?」
這個問題的答案,才真正決定資料應該怎麼組織。
這次最大的反直覺之一,就是我原本以為:
Partition、Clustering 都可以減少掃描,那就全部加上去。
但事情沒有這麼簡單。
如果資料本身很小,或者查詢方式非常單純,特別複雜的資料組織未必能帶來值得的收益。
真正有價值的是:
讓資料的組織方式符合實際使用方式。
Google Cloud 也提供 Partitioning 與 Clustering 的推薦機制,會根據實際工作負載與過去的查詢行為分析可能的最佳化方向。
這讓我想到一件事:
資料庫設計其實不是「一次決定,永遠不變」。
當資料量、查詢方式與使用者行為改變,原本合理的設計也可能需要重新檢查。
這是我查官方資料時覺得很有意思的一個延伸。
Google Cloud 在 2024 年推出 History-Based Optimizations,讓 BigQuery 可以參考過去相似查詢的執行結果,進一步尋找適合特定工作負載的最佳化方式。官方說明這類最佳化可以改善查詢時間、Slot 使用量以及處理資料量。
到了 2025 年,Google Cloud 又持續強化 BigQuery 的執行引擎,例如 Short Query Optimizations,讓部分短查詢可以採用更適合的執行方式,同時減少所需的計算資源。
到了 2026 年,Google Cloud 更進一步把 BigQuery 的發展方向描述成「持續自主最佳化」,讓平台利用歷史工作負載與執行資訊,持續改善效能與價格效能。
以前我們談 SQL 最佳化,很容易想到:
工程師自己研究 SQL → 找出瓶頸 → 自己調整。
現在則逐漸變成:
工程師負責建立合理的資料模型與查詢方式,平台本身也會參與後續最佳化。
但這不代表我們可以把 SQL 隨便寫。
這是我覺得最需要區分的一件事情。
BigQuery 現在確實越來越擅長自動最佳化。
但如果我從資料表設計開始,就完全沒有思考:
經過這次操作,我不會再只問:
「這個查詢有沒有跑成功?」
我會多問:
第一個問題:我真的需要這麼多資料嗎?
如果只是要回答一個小問題,就沒有必要讓整張資料表都參與。
第二個問題:資料表的組織方式符合查詢習慣嗎?
如果大家最常用日期查詢,日期可能就是值得考慮的 Partition 欄位。
如果經常依照某些欄位篩選或聚合,再考慮 Clustering。
第三個問題:這次查詢到底付出了什麼代價?
除了結果之外,也看看: