查詢計畫與時程

BigQuery 在查詢工作中內嵌了診斷查詢計劃和時間資訊。這類似於其他資料庫和分析系統中 EXPLAIN 等陳述式提供的資訊。您可以從 jobs.get 等方法的 API 回應中擷取這項資訊。

對於執行時間較長的查詢,BigQuery 會定期更新這些統計資料。這些更新會在工作狀態輪詢的頻率中獨立發生,但通常不會超過每 30 秒一次。此外,不使用執行資源的查詢工作 (例如模擬執行要求或可從快取結果提供的結果) 不會包含額外的診斷資訊,但可能會顯示其他統計資料。

背景

當 BigQuery 執行查詢工作時,會將宣告式 SQL 陳述式轉換成執行圖,圖中會把執行作業拆分成一系列的查詢階段,而這些階段是由更精細的執行步驟組合所組成的。BigQuery 會使用大量分散式平行架構來執行這些查詢。階段會模擬許多潛在工作站可能並行執行的工作單元。各階段會透過快速的分散式重組架構通訊。

在查詢計畫中,工作單元工作站一詞用於傳達並行處理的相關資訊。在 BigQuery 的其他部分,您可能會看到「運算單元」一詞,這是查詢執行作業的多個面向的抽象表示法,包括運算、記憶體和 I/O 資源。頂層工作統計資料會使用這項抽象會計的 totalSlotMs 估算值,估算個別查詢費用。

查詢執行架構的另一個重要屬性是動態性,也就是說,查詢執行期間可以修改查詢計畫。而在查詢執行期間所引進的階段,通常是用來改善資料在所有查詢工作站之間的分布狀況。在發生這種情況的查詢計畫中,這些階段通常會標示為重新分區階段

除了查詢計畫外,查詢工作也會顯示執行時程,提供查詢工作站已完成、待處理和作用中工作單位的計算。查詢可以同時有多個作用中工作站,各在不同的階段,因此時程主要是用來顯示查詢的整體進度。

透過 Google Cloud 控制台查看資訊

Google Cloud 主控台中,按一下「執行詳細資料」按鈕 (位於「結果」按鈕附近),即可查看已完成查詢的查詢計劃詳細資料。

查詢計畫。

查詢計劃資訊

在 API 回應中,查詢計畫會以查詢階段清單的形式呈現。清單中的每個項目都會顯示各階段的概覽統計資料、詳細步驟資訊和階段時間分類。並非所有詳細資料都會在 Google Cloud 控制台中顯示,但這些詳細資料都會出現在 API 回應中。

階段總覽

每個階段的總覽欄位可包含下列項目:

API 欄位 說明
id 階段的專屬數字 ID。
name 階段的簡式摘要名稱。階段中的 steps 會提供執行步驟的其他詳細資料。
status 階段的執行狀態。可能的狀態包括「待處理」、「執行中」、「已完成」、「失敗」及「已取消」。
inputStages 構成階段相依關係圖的 ID 清單。例如,JOIN 階段通常需要兩個相依階段,用來準備 JOIN 關係左右兩側的資料。
startMs 時間戳記 (以 UNIX 時間為單位),顯示階段中第一個工作站開始執行的時間。
endMs 時間戳記 (以 UNIX 時間為單位),顯示最後一個工作站執行完成的時間。
steps 階段中執行步驟的詳細清單。詳情請參閱下一節。
recordsRead 所有階段工作站中階段的輸入大小,以記錄數表示。
recordsWritten 所有階段工作站中階段的輸出大小,以記錄數表示。
parallelInputs 階段中可平行執行的工作單元數。視階段和查詢而定,這可能代表資料表內的資料欄區段數,或中繼洗牌作業中的分區數。
completedParallelInputs 階段中已完成的工作單元數。在某些查詢中,不一定要完成階段中的所有輸入後,該階段才能完成。
shuffleOutputBytes 代表某一查詢階段中所有工作站上的寫入位元組總數。
shuffleOutputBytesSpilled 在階段之間傳輸大量資料的查詢,可能需要以磁碟型傳輸為備用方法。溢位位元組統計資料會顯示溢出至磁碟的資料量。取決於最佳化演算法,因此無法針對任何指定查詢進行決定。

每階段時間分類

查詢階段提供相對和絕對兩種格式的階段時間分類。由於每個執行階段均代表一或多個獨立工作站執行的工作,因此提供的資訊會分成平均時間和最長時間兩種,這些時間代表某一階段中所有工作站的平均效能,以及指定分類中耗時最長的工作站效能。平均時間和最長時間會進一步分成絕對和相對表示法。在依比例的統計資料部分,會以任一區段中任何工作站所費的最長時間比例提供資料。

Google Cloud 控制台會使用相對時間表示法呈現階段時間。

階段時間資訊的報告如下所示:

相對時間 絕對時間 比例分子
waitRatioAvg waitMsAvg 一般工作站在等待排程上花費的時間。
waitRatioMax waitMsMax 最慢的工作站在等待排程上花費的時間。
readRatioAvg readMsAvg 一般工作站在讀取輸入資料上花費的時間。
readRatioMax readMsMax 最慢的工作站在讀取輸入資料上花費的時間。
computeRatioAvg computeMsAvg 平均工作站在 CPU 繫結上花費的時間。
computeRatioMax computeMsMax 最慢的工作站在 CPU 受限的情況下花費的時間。
writeRatioAvg writeMsAvg 一般工作站在寫入輸出資料上花費的時間。
writeRatioMax writeMsMax 最慢的工作站在寫入輸出資料上花費的時間。

步驟總覽

步驟包含每個工作站在階段中執行的作業,以作業的排序清單呈現。每個步驟作業都有一個類別,部分作業會提供更詳細的資訊。查詢計劃中的作業類別如下:

步驟類別 說明
READ 從輸入資料表或中繼重組中讀取一或多個資料欄。步驟詳細資料中只會傳回讀取的前 16 個資料欄。
WRITE 將一或多個資料欄寫入輸出資料表或中繼重組中。若是階段的 HASH 分區輸出,這也包含做為分區索引鍵使用的資料欄。
COMPUTE 運算式評估和 SQL 函式。
FILTER WHEREOMIT IFHAVING 子句使用。
SORT ORDER BY 作業,包含資料欄索引鍵和排序順序。
AGGREGATE GROUP BYCOUNT 等子句實作匯總功能。
LIMIT 實作 LIMIT 子句。
JOIN JOIN 等子句實作彙整作業,包括彙整類型和彙整條件。
ANALYTIC_FUNCTION 呼叫窗型函式 (又稱「分析函式」)。
USER_DEFINED_FUNCTION 對使用者定義函式的呼叫。

瞭解步驟詳細資料

BigQuery 提供步驟詳細資料,說明每個步驟在階段中執行的操作。如要找出查詢效能問題的來源,就必須瞭解階段中的步驟。

如要查看階段的步驟詳細資料,請按照下列步驟操作:

  1. 在「查詢結果」窗格中,按一下「執行圖表」

    「執行圖」分頁。

  2. 按一下您感興趣的階段,開啟包含階段資訊的面板。

  3. 在顯示階段資訊的面板中,前往「步驟詳細資料」部分。

    含有階段詳細資料的執行圖。

每個步驟都包含子步驟,用於說明該步驟的執行結果。子步驟會使用變數來說明步驟之間的關係。變數開頭為美元符號,後面接著不重複的數字。

以下是階段步驟詳細資料的範例,其中步驟之間共用變數:

READ
$30:l_orderkey, $31:l_quantity
FROM lineitem

AGGREGATE
GROUP BY $100 := $30
$70 := SUM($31)

WRITE
$100, $70
TO __stage00_output
BY HASH($100)

範例的步驟詳細資料如下:

  1. 這個階段會分別使用變數 $30$31,從資料表 lineitem 讀取資料欄 l_orderkeyl_quantity

  2. 這個階段會根據 $30$31 變數進行匯總,並分別將匯總結果儲存至 $100$70 變數。

  3. 這個階段會將 $100$70 變數的結果寫入 shuffle。這個階段使用 $100 將階段的結果排序,並進行隨機播放。

如果查詢的執行圖太複雜,提供完整的階段步驟詳細資料可能會在擷取查詢資訊時導致酬載大小問題,因此 BigQuery 可能會截斷步驟詳細資料。

透過查詢文字瞭解步驟

如需預先發布版期間的支援服務,請傳送電子郵件至 [email protected]

瞭解階段的步驟與查詢的關聯方式可能相當困難。「查詢文字」部分會顯示某些步驟與原始查詢文字的關聯性。

「查詢文字」部分會醒目顯示原始查詢文字的不同部分,並顯示將原始查詢文字與醒目顯示的查詢文字對應的步驟。只有原始查詢文字醒目顯示部分上方的步驟,才會套用至醒目顯示的查詢文字。

含有階段查詢文字的執行圖。

以下螢幕截圖範例顯示這些對應項目:

  • 步驟 AGGREGATE: GROUP BY $100 := $30 會對應回查詢文字 select l_orderkey

  • 步驟 READ: FROM lineitem 會對應回查詢文字 select ... from lineitem

  • 步驟 AGGREGATE: $70 := SUM($31) 會對應回查詢文字 sum(l_quantity)

並非所有步驟都能對應至查詢文字。

如果查詢使用檢視圖層,且階段的步驟已對應至檢視圖層的查詢文字,則「查詢文字」部分會顯示檢視圖層名稱和檢視圖層的查詢文字,並顯示對應項目。不過,如果檢視畫面遭到刪除,或是您失去檢視畫面的 bigquery.tables.get IAM 權限,則「查詢文字」部分不會顯示檢視畫面的階段步驟對應項目。

解讀及最佳化步驟

以下各節將說明如何解讀查詢計畫中的步驟,並提供查詢最佳化的方法。

READ

READ 步驟表示階段正在存取資料以供處理。您可以直接從查詢中參照的資料表,或從 Shuffle 記憶體中讀取資料。讀取前一個階段的資料時,BigQuery 會從排序記憶體讀取資料。使用預訂時,掃描的資料量會影響效能;使用隨選時段時,掃描的資料量會影響費用。

潛在效能問題

  • 對未分區資料表進行大量掃描:如果查詢只需要少部分資料,這可能表示資料表掃描效率不佳。分割可能是不錯的最佳化策略。
  • 掃描大型表格,但篩選比率偏低:這表示篩選器無法有效減少掃描的資料。建議您修改篩選條件。
  • Shuffle 位元組溢位至磁碟:這表示系統未使用叢集等最佳化技術有效儲存資料,因為叢集可能會在叢集中保留類似的資料。

最佳化

  • 指定篩選:有策略地使用 WHERE 子句,盡早在查詢中篩除不相關的資料。這麼做可減少查詢需要處理的資料量。
  • 分區和叢集:BigQuery 會使用資料表分區和叢集功能,有效率地找出特定資料區段。請務必根據常見的查詢模式,將資料表分區和分群,以便在 READ 步驟中盡量減少掃描的資料量。
  • 選取相關欄:避免使用 SELECT * 陳述式。請改為選取特定欄或使用 SELECT * EXCEPT,避免讀取不必要的資料。
  • 具體化檢視表:具體化檢視表可預先計算並儲存常用的匯總資料,因此在使用這些檢視表的查詢中,可能就不需要在 READ 步驟中讀取基礎資料表。

COMPUTE

COMPUTE 步驟中,BigQuery 會對您的資料執行下列動作:

  • 評估查詢的 SELECTWHEREHAVING 和其他子句中的運算式,包括計算、比較和邏輯運算。
  • 執行內建 SQL 函式和使用者定義函式。
  • 根據查詢中的條件篩選資料列。

最佳化

查詢計畫可揭露 COMPUTE 步驟中的瓶頸。找出需要大量運算或處理大量資料列的階段。

  • COMPUTE 步驟與資料量相關聯:如果某個階段顯示大量運算,且處理大量資料,那麼該階段可能適合進行最佳化。
  • 資料偏差:如果某個階段的運算時間上限遠高於運算時間平均值,表示該階段花費的時間不成比例,用於處理少數資料切片。建議您查看資料分布情形,看看是否有資料偏差。
  • 考量資料類型:為資料欄使用適當的資料類型。舉例來說,使用整數、日期/時間和時間戳記,而非字串,可以提升效能。

WRITE

WRITE 步驟會針對中繼資料和最終輸出結果執行。

  • 寫入 Shuffle 記憶體:在多階段查詢中,WRITE 步驟通常會將已處理的資料傳送至另一個階段,以便進一步處理。這通常是亂數記憶體的情況,因為亂數記憶體會結合或匯總來自多個來源的資料。這個階段寫入的資料通常是暫時結果,而非最終輸出內容。
  • 最終輸出內容:查詢結果會寫入目的地或暫時性資料表。

雜湊分區

當查詢計畫中的階段將資料寫入雜湊分割的輸出內容時,BigQuery 會寫入輸出內容中包含的資料欄,以及選擇做為分割鍵的資料欄。

最佳化

雖然 WRITE 步驟本身可能無法直接最佳化,但瞭解其角色有助於您在早期階段找出潛在瓶頸:

  • 盡量減少寫入的資料:專注於透過篩選和匯總來改善前置階段,以減少這個步驟中寫入的資料量。
  • 分區:寫入作業可從資料表分區中獲得極大助益。如果您寫入的資料僅限於特定分區,BigQuery 就能更快完成寫入作業。

    如果 DML 陳述式含有 WHERE 子句,且該子句針對資料表分區欄位設有靜態條件,則 BigQuery 只會修改相關的資料表分區。

  • 非正規化取捨:非正規化有時會導致中間 WRITE 步驟中的結果集較小。不過,這麼做也有缺點,例如儲存空間用量增加和資料一致性問題。

JOIN

JOIN 步驟中,BigQuery 會結合兩個資料來源的資料。彙整可包含彙整條件。彙整會耗用大量資源。在 BigQuery 中彙整大量資料時,系統會個別重組彙整索引鍵,以便在同一個分割區中排列,這樣就能在每個分割區中執行彙整作業。

JOIN 步驟的查詢計畫通常會顯示下列詳細資料:

  • 彙整模式:這會指出所使用的彙整類型。每個類型都會定義結果集要包含多少個已彙整資料表的資料列。
  • 彙整資料欄:這些資料欄用於比對資料來源之間的資料列。資料欄的選擇對於彙整效能至關重要。

彙整模式

  • 廣播彙整:當一個表格 (通常是較小的表格) 可放入單一 worker 節點或插槽的記憶體時,BigQuery 就能將該表格廣播至所有其他節點,以便有效執行彙整作業。請在步驟詳細資料中尋找 JOIN EACH WITH ALL
  • 雜湊運算:如果表格太大或不宜使用廣播運算,則可使用雜湊運算。BigQuery 會使用雜湊和洗牌運算來洗牌左側和右側的資料表,讓相符的鍵最終位於相同的運算單元,以便執行本機彙整。由於需要移動資料,因此雜湊運算是耗用資源的作業,但可讓系統在雜湊中有效比對資料列。請在步驟詳細資料中尋找 JOIN EACH WITH EACH
  • 自我彙整:SQL 反模式,其中資料表會與自身彙整。
  • 交叉彙整:SQL 反模式,因為產生的輸出資料量大於輸入資料,可能會導致嚴重效能問題。
  • 不均衡的彙整:在一個資料表中,彙整鍵的資料分布非常不均衡,可能會導致效能問題。請找出最長運算時間遠大於查詢計畫中平均運算時間的情況。詳情請參閱「高基數彙整」和「分區偏移」。

偵錯

  • 大量資料量:如果查詢計畫顯示在 JOIN 步驟中處理大量資料,請調查彙整條件和彙整鍵。建議您篩選或使用更具選擇性的彙整鍵。
  • 資料分布不均:分析合併鍵的資料分布情形。如果某個資料表的資料分布不均,請嘗試使用分割查詢或預先篩選等策略。
  • 高基數彙整:彙整產生的資料列數量遠多於左側和右側輸入資料列的數量,可能會大幅降低查詢效能。避免產生大量資料列的彙整。
  • 資料表排序錯誤:請確認您已選擇適當的彙整類型 (例如 INNERLEFT),並根據查詢需求依大小排序資料表。

最佳化

  • 選擇性彙整鍵:對於彙整鍵,請盡可能使用 INT64 而非 STRINGSTRING 比較會比較字串中的每個字元,因此速度比 INT64 比較慢。整數只需要單一比較。
  • 篩選器 (在彙整前):在彙整前,對個別資料表套用 WHERE 子句篩選器。這樣可減少參與彙整作業的資料量。
  • 避免在彙整欄上使用函式:避免在彙整欄上呼叫函式。請改為在擷取或擷取後的程序中,使用 ELT SQL 管道將資料表資料標準化。這種做法可避免動態修改彙整資料欄,讓彙整作業更有效率,同時不損害資料完整性。
  • 避免自連接:自連接通常用於計算依序列相關聯。不過,自我彙整可能會使輸出資料列數量增加四倍,導致效能問題。請考慮使用窗型 (分析) 函式,而非依賴自連接。
  • 先處理大型資料表:雖然 SQL 查詢最佳化工具可以判斷哪個資料表應位於彙整的哪一側,但請妥善排序彙整的資料表。最佳做法是先放置最大的表格,接著放置最小的表格,然後依大小遞減排序。
  • 去標準化:在某些情況下,有策略地去標準化資料表 (新增多餘資料) 可以完全消除彙整作業。不過,這種做法會犧牲儲存空間和資料一致性。
  • 分區和叢集:根據彙整索引鍵分割資料表,並叢集同區資料,可讓 BigQuery 指定相關資料分區,大幅加快彙整作業。
  • 最佳化偏移彙整:為避免偏移彙整造成的效能問題,請盡早篩選資料表中的資料,或將查詢拆分成兩個或多個查詢。

AGGREGATE

AGGREGATE 步驟中,BigQuery 會匯總及分組資料。

偵錯

  • 階段詳細資料:檢查匯總輸入列數和輸出列數,以及洗牌大小,以判斷匯總步驟可減少多少資料,以及是否涉及資料洗牌。
  • 重組大小:重組大小過大,可能表示在匯總期間,有大量資料在各工作站節點之間移動。
  • 檢查資料分布情形:確保資料在各個分區中均勻分布。資料分布不均可能導致匯總步驟的工作負載不平衡。
  • 查看匯總:分析匯總子句,確認其是否必要且有效率。

最佳化

  • 叢集:依據 GROUP BYCOUNT 或其他匯總子句中經常使用的資料欄,將資料表分組。
  • 區隔:選擇符合查詢模式的區隔策略。建議您使用擷取時間分區資料表,減少在匯總期間掃描的資料量。
  • 提早匯總:盡可能在查詢管道中提早執行匯總作業。這樣一來,匯總期間所需處理的資料量就會減少。
  • 洗牌最佳化:如果洗牌是瓶頸,請探索如何盡量減少洗牌次數。例如,將表格去除規格化或使用叢集功能,將相關資料放在相同位置。

極端案例

  • DISTINCT 匯總:含有 DISTINCT 匯總的查詢可能需要大量運算,尤其是在大型資料集上。如需近似結果,請考慮使用 APPROX_COUNT_DISTINCT 等替代方法。
  • 大量群組:如果查詢產生大量群組,可能會消耗大量記憶體。在這種情況下,請考慮限制群組數量或採用其他匯總策略。

REPARTITION

REPARTITIONCOALESCE 都是 BigQuery 直接套用至查詢中隨機排序資料的最佳化技巧。

  • REPARTITION此運算旨在重新平衡各工作節點的資料分布情形。假設在重新排序後,一個 worker 節點會產生不成比例的大量資料。REPARTITION 步驟會更平均地重新分配資料,避免任何單一工作站成為瓶頸。這對於需要大量運算的作業 (例如彙整) 尤其重要。
  • COALESCE如果在洗牌後有許多小資料區塊,就會執行這個步驟。COALESCE 步驟會將這些桶合併為較大的桶,藉此減少管理大量小型資料的額外負擔。在處理非常小的中間結果集時,這項功能尤其實用。

如果查詢計畫中顯示 REPARTITIONCOALESCE 步驟,不一定表示查詢有問題。這通常表示 BigQuery 正在主動最佳化資料分發作業,以提升效能。不過,如果您屢次看到這些作業,可能表示資料本身有偏差,或是查詢導致過度重複排序資料。

最佳化

如要減少 REPARTITION 步驟的數量,請嘗試以下做法:

  • 資料分布:確保資料表能有效地分區和分群。資料分布得越均勻,在重新洗牌後出現重大失衡的可能性就越低。
  • 查詢結構:分析查詢,找出資料偏差的潛在來源。舉例來說,是否有高度篩選的篩選器或彙整作業,導致在單一 worker 上處理的資料子集較小?
  • 彙整策略:嘗試使用不同的彙整策略,看看是否能帶來更均衡的資料分布。

如要減少 COALESCE 步驟的數量,請嘗試以下做法:

  • 匯總策略:請考慮在查詢管道中提早執行匯總作業。這有助於減少可能導致 COALESCE 步驟的小型中間結果集數量。
  • 資料量:如果您處理的資料集非常小,COALESCE 可能就不是個大問題。

請勿過度最佳化。過早進行最佳化可能會使查詢變得更複雜,卻沒有帶來顯著效益。

聯合查詢說明

聯合查詢可讓您使用 EXTERNAL_QUERY 函式,將查詢陳述式傳送至外部資料來源。聯合查詢會採用稱為 SQL 推送的最佳化技術,而查詢計畫會顯示推送至外部資料來源的作業 (如果有)。舉例來說,如果您執行以下查詢:

SELECT id, name
FROM EXTERNAL_QUERY("<connection>", "SELECT * FROM company")
WHERE country_code IN ('ee', 'hu') AND name like '%TV%'

查詢計畫會顯示下列階段步驟:

$1:id, $2:name, $3:country_code
FROM table_for_external_query_$_0(
  SELECT id, name, country_code
  FROM (
    /*native_query*/
    SELECT * FROM company
  )
  WHERE in(country_code, 'ee', 'hu')
)
WHERE and(in($3, 'ee', 'hu'), like($2, '%TV%'))
$1, $2
TO __stage00_output

在這個計畫中,table_for_external_query_$_0(...) 代表 EXTERNAL_QUERY 函式。您可以在括號中看到外部資料來源執行的查詢。因此,您會發現:

  • 外部資料來源只會傳回 3 個所選欄位。
  • 外部資料來源只會傳回 country_code'ee''hu' 的資料列。
  • LIKE 運算子不會推送至下層,而是由 BigQuery 評估。

比較來說,如果沒有推送,查詢計畫會顯示下列階段步驟:

$1:id, $2:name, $3:country_code
FROM table_for_external_query_$_0(
  SELECT id, name, description, country_code, primary_address, secondary address
  FROM (
    /*native_query*/
    SELECT * FROM company
  )
)
WHERE and(in($3, 'ee', 'hu'), like($2, '%TV%'))
$1, $2
TO __stage00_output

這次外部資料來源會傳回 company 資料表的所有欄和資料列,而 BigQuery 會執行篩選。

時程中繼資料

查詢時程提供整體查詢進度的快照視圖,以報告特定時間點的進度。時程以一系列的樣本表示,這些樣本會回報下列詳細資料:

欄位 說明
elapsedMs 查詢開始執行後經歷的毫秒數。
totalSlotMs 查詢使用的運算單元毫秒數的累計表示法。
pendingUnits 已排定和等待執行的工作單元總數。
activeUnits 工作站正在處理的工作單元總數。
completedUnits 執行這項查詢時已完成的工作單元總數。

查詢範例

下列查詢會計算莎士比亞公開資料集中的列數,而查詢的第二個條件是將結果侷限在參照「hamlet」的列:

SELECT
  COUNT(1) as rowcount,
  COUNTIF(corpus = 'hamlet') as rowcount_hamlet
FROM `publicdata.samples.shakespeare`

按一下「執行詳細資料」即可查看查詢計畫:

hamlet 查詢計畫。

色彩指標會顯示所有階段中所有步驟的相對時間。

如要進一步瞭解執行階段的步驟,請按一下 展開階段的詳細資料:

hamlet 查詢計畫步驟詳細資料。

在這個範例中,所有區段中耗費最長時間的是單一工作站在階段 01 等待階段 00 完成的時間。這是因為階段 01 需要有階段 00 的輸入,所以必須在第一個階段將輸出寫入中繼 Shuffle 後才能開始。

錯誤報告

查詢工作可能會在執行中失敗。因為系統會定期更新計劃資訊,所以您可以在執行圖中觀察到失敗的發生位置。在 Google Cloud 控制台中,階段名稱旁的勾號或驚嘆號分別標示著這個階段成功或失敗。

如要進一步瞭解如何解讀及解決錯誤,請參閱疑難排解指南

API 表示法範例

查詢計劃資訊會內嵌於工作回應資訊,您可以呼叫 jobs.get 擷取該資訊。例如,以下摘錄了傳回哈姆雷特查詢範例的工作 JSON 回應,其中顯示查詢計劃和時程資訊。

"statistics": {
  "creationTime": "1576544129234",
  "startTime": "1576544129348",
  "endTime": "1576544129681",
  "totalBytesProcessed": "2464625",
  "query": {
    "queryPlan": [
      {
        "name": "S00: Input",
        "id": "0",
        "startMs": "1576544129436",
        "endMs": "1576544129465",
        "waitRatioAvg": 0.04,
        "waitMsAvg": "1",
        "waitRatioMax": 0.04,
        "waitMsMax": "1",
        "readRatioAvg": 0.32,
        "readMsAvg": "8",
        "readRatioMax": 0.32,
        "readMsMax": "8",
        "computeRatioAvg": 1,
        "computeMsAvg": "25",
        "computeRatioMax": 1,
        "computeMsMax": "25",
        "writeRatioAvg": 0.08,
        "writeMsAvg": "2",
        "writeRatioMax": 0.08,
        "writeMsMax": "2",
        "shuffleOutputBytes": "18",
        "shuffleOutputBytesSpilled": "0",
        "recordsRead": "164656",
        "recordsWritten": "1",
        "parallelInputs": "1",
        "completedParallelInputs": "1",
        "status": "COMPLETE",
        "steps": [
          {
            "kind": "READ",
            "substeps": [
              "$1:corpus",
              "FROM publicdata.samples.shakespeare"
            ]
          },
          {
            "kind": "AGGREGATE",
            "substeps": [
              "$20 := COUNT($30)",
              "$21 := COUNTIF($31)"
            ]
          },
          {
            "kind": "COMPUTE",
            "substeps": [
              "$30 := 1",
              "$31 := equal($1, 'hamlet')"
            ]
          },
          {
            "kind": "WRITE",
            "substeps": [
              "$20, $21",
              "TO __stage00_output"
            ]
          }
        ]
      },
      {
        "name": "S01: Output",
        "id": "1",
        "startMs": "1576544129465",
        "endMs": "1576544129480",
        "inputStages": [
          "0"
        ],
        "waitRatioAvg": 0.44,
        "waitMsAvg": "11",
        "waitRatioMax": 0.44,
        "waitMsMax": "11",
        "readRatioAvg": 0,
        "readMsAvg": "0",
        "readRatioMax": 0,
        "readMsMax": "0",
        "computeRatioAvg": 0.2,
        "computeMsAvg": "5",
        "computeRatioMax": 0.2,
        "computeMsMax": "5",
        "writeRatioAvg": 0.16,
        "writeMsAvg": "4",
        "writeRatioMax": 0.16,
        "writeMsMax": "4",
        "shuffleOutputBytes": "17",
        "shuffleOutputBytesSpilled": "0",
        "recordsRead": "1",
        "recordsWritten": "1",
        "parallelInputs": "1",
        "completedParallelInputs": "1",
        "status": "COMPLETE",
        "steps": [
          {
            "kind": "READ",
            "substeps": [
              "$20, $21",
              "FROM __stage00_output"
            ]
          },
          {
            "kind": "AGGREGATE",
            "substeps": [
              "$10 := SUM_OF_COUNTS($20)",
              "$11 := SUM_OF_COUNTS($21)"
            ]
          },
          {
            "kind": "WRITE",
            "substeps": [
              "$10, $11",
              "TO __stage01_output"
            ]
          }
        ]
      }
    ],
    "estimatedBytesProcessed": "2464625",
    "timeline": [
      {
        "elapsedMs": "304",
        "totalSlotMs": "50",
        "pendingUnits": "0",
        "completedUnits": "2"
      }
    ],
    "totalPartitionsProcessed": "0",
    "totalBytesProcessed": "2464625",
    "totalBytesBilled": "10485760",
    "billingTier": 1,
    "totalSlotMs": "50",
    "cacheHit": false,
    "referencedTables": [
      {
        "projectId": "publicdata",
        "datasetId": "samples",
        "tableId": "shakespeare"
      }
    ],
    "statementType": "SELECT"
  },
  "totalSlotMs": "50"
},

使用執行資訊

BigQuery 查詢計畫會提供服務執行查詢的方式相關資訊,但服務的代管性質限制了部分詳細資料是否可以直接操作。使用這項服務時,許多最佳化作業會自動執行,這與其他環境不同,在其他環境中,調整、佈建和監控作業可能需要專業知識豐富的專員。

如要瞭解可改善查詢執行和效能的具體技巧,請參閱最佳做法說明文件。查詢計畫和時程統計資料可協助您瞭解是否有特定階段霸占資源使用量。例如,JOIN 階段產生的輸出資料列比輸入資料列多很多,可能表示可以在查詢中更早進行篩選。

此外,時間軸資訊有助於判斷特定查詢是否因獨立執行而變慢,或是因其他查詢爭用相同資源而導致效能變慢。如果您發現作用中的單元數在整個查詢生命週期中依然有限,但已排入佇列的工作單元數量卻一直很高,這可能代表減少並行查詢的數量會大幅改善某些查詢的整體執行時間。