(一樣是接續前一篇文章)
減少要處理的資料
建議不要使用SELECT *
僅查詢所需欄位,控管投影。投影指的是查詢作業讀取的欄位數。投影多餘的資料欄會產生額外的(浪費)I/O和具體化(寫入結果)。避免使用依日期進行資料分割的資料表
請勿使用依日期進行資料分割的資料表(又稱為以日期命名的資料表)來取代時間分區資料表。分區資料表的執行效果比以日期命名的資料表好。當建立依日期進行資料分割的資料表時,BigQuery必須為每個以日期命名的資料表保留一份結構定義與中繼資料的複本。同時,當使用以日期命名的資料表時,BigQuery可能需要驗證每個查詢資料表的權限。這個做法也會增加查詢的負擔,並影響查詢效能。
使用JOIN之前減少資料
執行匯總作業,減少在JOIN子句之前處理的資料量。如果查詢含有GROUP BY和JOIN,請在查詢的較前位置執行匯總,以減少處理的資料量。另外,使用GROUP BY子句搭配匯總函式會耗費大量運算資源,因為這類查詢會使用洗牌。由於這些查詢的運算量很大,因此請務必只在必要時使用GROUP BY子句。
使用具體化檢視表
具體化檢視表是預先運算的檢視表,會定期快取查詢結果,以提升效能和效率。
最佳化查詢作業
避免對相同的CTE進行多次評估
如果查詢包含在查詢中多個位置使用的通用表格運算式(CTE),這些運算式可能會在每次參照時進行評估。查詢最佳化工具會嘗試偵測可執行一次的查詢部分,但這不一定可行。因此,使用CTE可能無法減少內部查詢的複雜度和資源消耗量。可以根據CTE傳回的資料,將CTE的結果儲存在標量變數或臨時表格中。
避免重複的資料彙整與子查詢
相較於重複彙整資料,使用巢狀、重複的資料來表示關係可能更有效率。若使用巢狀、重複的資料,彙整作業所需的通訊頻寬就不會對效能產生影響。如此一來,也能節省重複讀取及寫入相同資料所產生的I/O成本。同樣的,重複執行相同的子查詢也會因重複的查詢處理作業而對效能造成影響。如果要在多個查詢中使用相同的子查詢,請考慮具體化資料表中的子查詢結果,然後在查詢中使用經過具體化的資料。
將結合模式最佳化
最佳做法是先放置資料列數量最多的表格,接著放置資料列數量最少的表格,然後依大小遞減順序放置其餘的表格。將大型資料表放在JOIN的左邊,並將小型資料表放在JOIN的右邊時,便建立了傳播結合。傳播結合會將較小資料表中的所有資料傳送至處理較大資料表的每個運算單元。建議先執行傳播結合。
最佳化ORDER BY子句
使用ORDER BY子句時,請務必遵循下列最佳做法:
- 在最外側查詢或window子句中使用ORDER BY。將複雜作業推送至查詢結尾。
- 使用LIMIT子句。如果您要排序的值非常大量,但不需要全部傳回,請使用LIMIT子句。
- 使用窗型函式。如果要排序的值非常多,請使用窗型函式,並在呼叫窗型函式前限制資料。
在彙整中使用INT64資料類型
BigQuery不會像傳統資料庫一樣為主鍵建立索引,因此彙整資料欄的範圍越廣,比較所需的時間就越長。因此,在彙整作業中使用INT64資料類型比使用STRING資料類型更省錢且更有效率。
避免SQL反模式
避免自我彙整
避免交叉彙整
避免更新或插入單列的DML陳述式
使用單點DML陳述式代表想將BigQuery當成線上交易處理(OLTP)系統。BigQuery著重於使用資料表掃描進行線上分析處理(OLAP)上,而不是點查詢。如果需要與OLTP類似的功能(單列更新或插入),請考慮使用專為支援OLTP用途設計的資料庫,例如Cloud SQL。
BigQuery DML陳述式適用於批次更新。BigQuery中的UPDATE和DELETE DML陳述式較適合定期重寫資料,而非單列異動。INSERT DML陳述式適合少量使用。插入作業使用的修改配額與載入工作相同。如果使用案例涉及頻繁的單列插入,請考慮改為串流資料。
來源文件:最佳化調整查詢運算