排解效能迴歸問題

使用 SQL 查詢查詢資料時,Spanner 會自動使用可能有助於更有效率地擷取資料的任何次要索引。然而,在少數情況下,Spanner 可能會選擇造成查詢速度變慢的索引。因此,您可能會發現某些查詢的執行速度比以往慢。

本頁面說明如何偵測查詢執行速度的變化、檢查這些查詢的查詢執行計畫,以及視需要為日後的查詢指定其他索引。

偵測查詢執行速度的變化

進行下列變更後,查詢執行速度最有可能會改變:

  • 大幅變更大量現有資料,且這些資料具有次要索引。
  • 新增、變更或捨棄次要索引。

你可以使用幾種不同的工具,找出 Spanner 執行速度比平常慢的特定查詢:

  • 查詢洞察查詢統計資料
  • 延遲指標

  • 您可使用 Cloud Monitoring 擷取及分析特定應用程式指標。舉例來說,您可以監控「查詢次數」指標,判斷執行個體在一段時間內的查詢次數,並找出執行查詢時使用的查詢最佳化工具版本。

  • 可測量應用程式效能的用戶端監控工具。

新資料庫注意事項

使用新插入或匯入的資料查詢新建立的資料庫時,Spanner 可能不會選取最合適的索引,因為查詢最佳化工具最多需要三天才能自動收集最佳化工具統計資料。如要比上述時間更早最佳化新 Spanner 資料庫的索引使用情形,可以手動建構新的統計資料套件

查看結構定義

找出速度變慢的查詢後,請查看該查詢的 SQL 陳述式,並找出陳述式使用的資料表,以及從這些資料表擷取的資料欄。

接著,找出這些資料表的次要索引。 判斷是否有任何索引包含您要查詢的資料欄,這表示 Spanner 可能會使用其中一個索引來處理查詢。

  • 如有適用的索引,下一步是找出 Spanner 用於查詢的索引
  • 如果沒有適用的索引,請使用 gcloud spanner operations list 指令檢查您最近是否捨棄了適用的索引:

    gcloud spanner operations list \
        --instance=INSTANCE \
        --database=DATABASE \
        --filter="@TYPE:UpdateDatabaseDdlMetadata"
    

    如果您捨棄適用的索引,這項變更可能會影響查詢效能。將次要索引加回資料表。Spanner 新增索引後,請再次執行查詢並查看其效能。如果效能沒有提升,請找出 Spanner 用於查詢的索引

    如果沒有捨棄適用的索引,索引選取作業就不會導致查詢效能倒退。找出可能影響成效的資料或使用模式變化。

找出查詢使用的索引

如要瞭解 Spanner 用來處理查詢的索引,請在 Google Cloud 控制台中查看查詢執行計畫

  1. 前往Google Cloud 控制台的 Spanner「Instances」(執行個體) 頁面。

    前往「Instances」(執行個體) 頁面

  2. 按一下要查詢的執行個體名稱。

  3. 在左側窗格中,按一下要查詢的資料庫,然後點選「Spanner Studio」

  4. 輸入要測試的查詢。

  5. 在「執行查詢」下拉式清單中,選取「僅說明」。 Spanner 會顯示查詢計畫。

在查詢計畫中尋找下列至少一個運算子:

  • 掃描桌子
  • 索引掃描
  • Cross applydistributed cross apply

以下各節將說明每個運算子的意義。

資料表掃描運算子

資料表掃描運算子表示 Spanner 未使用次要索引:

螢幕截圖:顯示查詢計畫中的資料表掃描運算子。

舉例來說,假設 Albums 資料表沒有任何次要索引,而您執行下列查詢:

SELECT AlbumTitle FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

由於沒有可用的索引,查詢計畫包含資料表掃描運算子。

索引掃描運算子

索引掃描運算子表示 Spanner 在處理查詢時使用了次要索引:

螢幕截圖:顯示查詢計畫中的索引掃描運算子。

舉例來說,假設您在 Albums 資料表中新增索引:

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

然後執行下列查詢:

SELECT AlbumTitle FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

AlbumsByAlbumTitle 索引包含 AlbumTitle,這是查詢選取的唯一資料欄。因此,查詢計畫會包含索引掃描運算子。

Cross apply 運算子

在某些情況下,Spanner 會使用只包含查詢所選部分資料欄的索引。因此,Spanner 必須將索引與基本資料表聯結。

發生這類聯結時,查詢計畫會包含 cross applydistributed cross apply 運算子,並具有下列輸入內容:

  • 資料表索引的索引掃描運算子
  • 擁有索引的資料表之資料表掃描運算子

螢幕截圖:顯示查詢計畫中的分散式交叉套用,其中索引掃描和表格掃描是輸入內容。

舉例來說,假設您在 Albums 資料表中新增索引:

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

然後執行下列查詢:

SELECT * FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

AlbumsByAlbumTitle 索引包含 AlbumTitle,但查詢會選取資料表中的所有資料欄,而不只是 AlbumTitle。因此,查詢計畫會包含 distributed cross apply 運算子,並以 AlbumsByAlbumTitle 的索引掃描和 Albums 的資料表掃描做為輸入。

選擇其他索引

找出 Spanner 用於查詢的索引後,請嘗試使用其他索引執行查詢,或掃描主資料表,而非使用索引。如要指定索引,請在查詢中加入 FORCE_INDEX 指令

如果找到速度更快的查詢版本,請更新應用程式,改用速度較快的版本。

選擇索引的指南

請參考下列規範,決定要測試查詢的哪個索引:

  • 如果查詢符合上述任一條件,請嘗試使用主資料表,而非次要索引:

    • 查詢會檢查與基本資料表主鍵前置字串的等值 (例如 SELECT * FROM Albums WHERE SingerId = 1)。
    • 大量資料列符合查詢述詞 (例如 SELECT * FROM Albums WHERE AlbumTitle != "There Is No Album With This Title")。
    • 查詢使用的基礎資料表只包含幾百列。
  • 如果查詢包含非常具選擇性的述詞 (例如 REGEXP_CONTAINSSTARTS_WITH<<=>>=!=),請嘗試使用包含述詞中所用相同資料欄的索引。

測試更新後的查詢

使用 Google Cloud 控制台測試更新後的查詢,並瞭解處理查詢所需的時間。

如果查詢包含查詢參數,且查詢參數繫結至某些值的頻率遠高於其他值,請在測試中將查詢參數繫結至其中一個值。舉例來說,如果查詢包含 WHERE country = @countryId 等述詞,且幾乎所有查詢都會將 @countryId 繫結至 US 值,則請在效能測試中將 @countryId 繫結至 US。這種做法有助於針對最常執行的查詢進行最佳化。

如要在 Google Cloud 控制台中測試更新後的查詢,請按照下列步驟操作:

  1. 前往Google Cloud 控制台的 Spanner「Instances」(執行個體) 頁面。

    前往「Instances」(執行個體) 頁面

  2. 按一下要查詢的執行個體名稱。

  3. 在左側窗格中,點選要查詢的資料庫,然後按一下「Spanner Studio」

  4. 輸入要測試的查詢 (包括 FORCE_INDEX 指令),然後按一下「執行查詢」

    控制台會開啟「結果表格」分頁,然後顯示查詢結果,包括 Spanner 服務處理查詢所花費的時間。 Google Cloud

    這項指標不包含其他延遲來源,例如 Google Cloud 控制台解讀及顯示查詢結果所用的時間。

使用 REST API 取得 JSON 格式的查詢詳細設定檔

根據預設,執行查詢時只會傳回陳述式結果。這是因為 QueryMode 設為 NORMAL。如要在查詢結果中加入詳細的執行統計資料,請將 QueryMode 設為 PROFILE

建立工作階段

更新查詢模式前,請先建立工作階段,代表與 Spanner 資料庫服務的通訊管道。

  1. 按一下 [projects.instances.databases.sessions.create]
  2. 請以以下格式提供專案執行個體資料庫 ID:

    projects/[\PROJECT_ID]/instances/[\INSTANCE_ID]/databases/[\DATABASE_ID]

  3. 按一下 [Execute] (執行)。回應會顯示您在這個表單中建立的會話:

    projects/[\PROJECT_ID]/instances/[\INSTANCE_ID]/databases/[\DATABASE_ID]/sessions/[\SESSION]

    您會在下一個步驟中使用此項目執行查詢設定檔。建立的連線最多可存續一小時,之後就會由資料庫刪除。

剖析查詢

為查詢啟用 PROFILE 模式。

  1. 按一下 projects.instances.databases.sessions.executeSql
  2. 在「session」中,輸入您在上一個步驟中建立的工作階段 ID:

    projects/[PROJECT_ID]/instances/[INSTANCE_ID]/databases/[DATABASE_ID]/sessions/[SESSION]

  3. 在「Request body」部分,使用下列程式碼:

    { "sql": "[YOUR_SQL_QUERY]", "queryMode": "PROFILE" }

  4. 按一下 [Execute] (執行)。傳回的回應會包含查詢結果、查詢計畫和查詢的執行統計資料。