查詢計劃與時程

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

若為長時間執行的查詢,BigQuery 會定期更新這些統計資料。統計資料更新的頻率與工作狀態的輪詢頻率無關,但一般而言,最頻繁的更新頻率每 30 秒一次。此外,未使用執行資源的查詢工作 (例如可以由快取結果提供的模擬測試要求或結果) 將不會含有其他診斷資訊,但可能會顯示其他統計資料。

背景

當 BigQuery 執行查詢工作時,會將宣告 SQL 陳述式轉換成執行圖,圖中會分解成一連串的查詢階段,而這些階段本身是由更精細的執行步驟集所組成。BigQuery 會使用大量分散式平行架構來執行這些查詢,而這些階段則會建立許多潛在工作站可能並行執行的工作單元模型。這些階段會透過快速分散式 Shuffle 架構彼此通訊,這種架構的詳細說明請見說明文章

在查詢計劃中會使用工作單元和工作站這些詞彙,因為計劃就是專門用來傳達平行化的相關資訊。在 BigQuery 的其他地方,您可能會遇到「運算單元」一詞,這是查詢執行多重面向的抽象表示,包括計算、記憶體及 I/O 資源。頂層工作統計資料則藉由這個抽象帳目使用查詢 totalSlotMs 估算,提供個別查詢費用的估計值。

動態是查詢執行架構的另一個重要屬性,這表示可以在執行查詢時修改查詢計劃。正在執行查詢時產生的階段,通常是用來改善所有查詢工作站的資料分送。在查詢計劃中如有這種情形,這些階段通常會加上「重新分割」的標籤。

除了查詢計劃外,查詢工作也會顯示執行的時程,其中提供查詢工作站已完成、待處理及作用中的工作單元帳目。查詢可以同時有多個階段與作用中工作站,因此時程主要是用來顯示查詢的整體進度。

使用 BigQuery 傳統網頁版 UI 查看資訊

如果您使用 BigQuery 傳統網頁版 UI,按一下 [Details] 按鈕 ([Results] 按鈕的右邊),將會看到已完成查詢的查詢計劃詳細資料。

查詢計劃的螢幕擷取畫面

對於長時間執行的查詢,您可以在查詢編輯器窗格的下方,按一下查詢狀態行中的連結,就可以查看進行中的查詢計劃。

經歷時間狀態行的螢幕擷取畫面

查詢計劃資訊

在 API 回應中,查詢計劃是以查詢階段清單表示,其中顯示每個階段的統計資料總覽、詳細的步驟資訊,以及階段時間分類。並非所有詳細資訊都會顯示在網頁版 UI 中,但可能會出現在 API 回應中。

階段總覽

每個階段的總覽欄位可能包含下列資訊:

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

每階段步驟資訊

步驟代表每個工作站必須在階段中執行的更精細作業,以作業的排序清單呈現。步驟會加以分類,且部分作業會提供更詳細的資訊。查詢計劃中的作業類別如下:

步驟 說明
READ 從輸入資料表或中繼 Shuffle 中讀取一或多個資料欄。
WRITE 將一或多個資料欄寫入到輸出資料表或中繼結果。針對階段中的 HASH 分區輸出,這也包含作為分區金鑰使用的資料欄。
COMPUTE 運算式評估和 SQL 函式之類的作業。
FILTER 實作 WHERE、OMIT IF 與 HAVING 子句的運算子。
SORT 排序或排序依據作業,包括資料欄鍵和方向。
AGGREGATE 匯總作業,例如 GROUP BY 或 COUNT。
LIMIT 實作 LIMIT 子句的運算子。
JOIN 一種 JOIN 運算,包括聯結類型和使用的資料欄。
ANALYTIC_FUNCTION 叫用分析函式 (又稱為「窗型函式」)。
USER_DEFINED_FUNCTION 呼叫使用者定義的函式。

每階段時間分類

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

BigQuery 傳統網頁版 UI 利用相對時間表示法來呈現階段時間。

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

相對時間 絕對時間 BigQuery 傳統網頁版 UI* 比例分子 **
waitRatioAvg waitMsAvg waitRatioAvg 深黃色列 一般工作站在等待排程上花費的時間。
waitRatioMax waitMsMax waitRatioMax 黃色列 最慢的工作站在等待排程上花費的時間。
readRatioAvg readMsAvg readRatioAvg 深紫色列 一般工作站在讀取輸入資料上花費的時間。
readRatioMax readMsMax readRatioMax 紫色列 最慢的工作站在讀取輸入資料上花費的時間。
computeRatioAvg computeMsAvg computeRatioAvg 深橙色列 一般工作站在 CPU 處理上花費的時間。
computeRatioMax computeMsMax computeRatioMax 橙色列 最慢的工作站在 CPU 處理上花費的時間。
writeRatioAvg writeMsAvg writeRatioAvg 深藍色列 一般工作站在寫入輸出資料上花費的時間。
writeRatioMax writeMsMax writeRatioMax 藍色列 最慢的工作站在寫入輸出資料上花費的時間。

*「AVG」與「MAX」標籤只是圖例,不會顯示在 BigQuery 傳統網頁版 UI 中。

時程中繼資料

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

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

查詢範例

如果您執行一個簡單的查詢,要計算莎士比亞公開資料集中的列數,而查詢的第二個條件是將結果侷限在參照哈姆雷特的列:

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

您可以按一下 [Details],查看有關查詢計劃的下列資訊。首先,讓我們先檢查第一個區段,其中含有查詢時程:

哈姆雷特查詢時程螢幕擷取畫面

在本例中,我們要處理非常小的樣本資料表和簡單查詢,所有總計只有兩個工作單元。這個範例中的所有工作幾乎是立即完成。

所以,讓我們再往下看看查詢計劃:

哈姆雷特查詢計劃螢幕擷取畫面

在本例中,顏色指標顯示所有階段的相對時間。在平行輸入資訊中,我們看到各階段都只需要一個工作站,因此平均時間和最長時間沒有差異。

我們還看到,在這個小型查詢中,所有區段中耗費最長時間的是單一工作站在階段 01 等待階段 00 完成的時間。這是因為階段 01 需要有階段 00 的輸入,所以必須在第一個階段將輸出 (1 列,約 18 位元組) 寫入中繼 Shuffle 後才能開始。

現在,讓我們更仔細地檢查執行階段步驟。在階段標籤的左側,點選三角形以展開階段的詳細資料:

哈姆雷特查詢計劃步驟詳細資訊螢幕擷取畫面

在這個案例中,我們看到已完成階段 00 工作的單一工作站執行計劃。首先,先從參照莎士比亞資料表的「corpus」資料欄讀取 (READ) 資料。接下來,建立 COUNTCOUNTIF 預測的匯總 (AGGREGATIONS)。掃描資料需要計算 (COMPUTE) 步驟,這會提供標準和條件計數的資料,然後將輸出寫入這個計劃中標示為 __stage00_output 的中繼 Shuffle 輸出。

錯誤報告

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

如要進一步瞭解解譯和解決錯誤,請參閱疑難排解指南

API 表示法範例

查詢計劃資訊會自動內嵌於工作回應資訊,無需呼叫其他方法,且只要呼叫 jobs.get 就可以擷取詳細的工作資訊。例如,下面摘錄了傳回哈姆雷特查詢範例的工作 JSON 回應,其中顯示查詢計劃和時程資訊。

"statistics": {
  "query": {
    "cacheHit": false,
    "queryPlan": [
      {
        "completedParallelInputs": "1",
        "computeMsAvg": "25",
        "computeMsMax": "25",
        "computeRatioAvg": 0.17857142857142858,
        "computeRatioMax": 0.17857142857142858,
        "endMs": "1522787349945",
        "id": "0",
        "name": "S00: Input",
        "parallelInputs": "1",
        "readMsAvg": "28",
        "readMsMax": "28",
        "readRatioAvg": 0.2,
        "readRatioMax": 0.2,
        "recordsRead": "164656",
        "recordsWritten": "1",
        "shuffleOutputBytes": "18",
        "shuffleOutputBytesSpilled": "0",
        "startMs": "1522787349898",
        "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"
            ]
          }
        ],
        "waitMsAvg": "0",
        "waitMsMax": "0",
        "waitRatioAvg": 0.0,
        "waitRatioMax": 0.0,
        "writeMsAvg": "5",
        "writeMsMax": "5",
        "writeRatioAvg": 0.03571428571428571,
        "writeRatioMax": 0.03571428571428571
      },
      {
        "completedParallelInputs": "1",
        "computeMsAvg": "14",
        "computeMsMax": "14",
        "computeRatioAvg": 0.1,
        "computeRatioMax": 0.1,
        "endMs": "1522787350180",
        "id": "1",
        "inputStages": [
          "0"
        ],
        "name": "S01: Output",
        "parallelInputs": "1",
        "readMsAvg": "0",
        "readMsMax": "0",
        "readRatioAvg": 0.0,
        "readRatioMax": 0.0,
        "recordsRead": "1",
        "recordsWritten": "1",
        "shuffleOutputBytes": "16",
        "shuffleOutputBytesSpilled": "0",
        "startMs": "1522787350038",
        "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"
            ]
          }
        ],
        "waitMsAvg": "140",
        "waitMsMax": "140",
        "waitRatioAvg": 1.0,
        "waitRatioMax": 1.0,
        "writeMsAvg": "129",
        "writeMsMax": "129",
        "writeRatioAvg": 0.9214285714285714,
        "writeRatioMax": 0.9214285714285714
      }
    ],
    "referencedTables": [
      {
        "datasetId": "samples",
        "projectId": "publicdata",
        "tableId": "shakespeare"
      }
    ],
    "statementType": "SELECT",
    "timeline": [
      {
        "activeUnits": "0",
        "completedUnits": "2",
        "elapsedMs": "999",
        "pendingUnits": "0",
        "totalSlotMs": "185"
      },
      {
        "activeUnits": "0",
        "completedUnits": "2",
        "elapsedMs": "1197",
        "pendingUnits": "0",
        "totalSlotMs": "185"
      }
    ],
    "totalBytesBilled": "10485760",
    "totalBytesProcessed": "2464625",
    "totalPartitionsProcessed": "0",
    "totalSlotMs": "127"
  },
  "totalBytesProcessed": "2464625"
},

使用執行資訊

BigQuery 查詢計劃提供關於服務如何執行查詢的資訊,但服務的代管性質限制了部分詳細資訊是否可以直接操作。只要使用服務,許多最佳化作業就會自動進行,相較於需要相關專業人員才能調整、佈建和監控的其他環境,這項服務非常不一樣。

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

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

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁