如何判斷是否發生外部下推

本文詳細會說明如何判斷 PolyBase 查詢是否會受益於下推至外部資料來源。 如需外部下推的詳細資訊,請參閱 PolyBase 中的下推計算

我的查詢是否會受益於外部下推?

下推計算可改善外部資料來源的查詢效能。 某些計算工作會委派給外部資料來源,而不是被傳送至 SQL Server。 特別是在篩選和聯結下推的情況下,SQL Server 執行個體上的工作負載可以大幅減少。

PolyBase 下推計算可以大幅改善查詢的效能。 如果 PolyBase 查詢執行速度緩慢,應該判斷是否發生了 PolyBase 查詢下推。

執行計畫中可以觀察三種不同的下推案例:

  • 篩選器述詞下推
  • 加入下推
  • 彙總下推

注意

使用 PolyBase 下推計算,在下推至外部資料來源時會受到限制:

已引進 SQL Server 2019 (15.x) 的兩項新功能,允許系統管理員判斷 PolyBase 查詢是否已向下推送至外部資料來源:

本文提供如何針對三個下推案例使用兩種使用案例詳細資料。

使用 TF6408

根據預設,預估執行計畫不會公開遠端查詢計畫,而只會顯示遠端查詢運算子物件。 例如,來自 SQL Server Management Studio 的估計執行計畫 (SSMS):

A screenshot of an estimated execution plan in SSMS.

或者,在 Azure Data Studio 中:

A screenshot of an estimated execution plan from Azure Data Studio.

從 SQL Server 2019 (15.x) 開始,您可以使用 DBCC TRACEON 全域啟用新的追蹤旗標 6408。 例如:

DBCC TRACEON (6408, -1);  

此追蹤旗標僅適用於預估的執行計畫,而且不會影響實際執行計畫。 此追蹤旗標會公開遠端查詢運算子的相關資訊,顯示遠端查詢階段發生的情況。

執行計畫會從右至左讀取,如箭頭的方向所指示。 如果運算在位於另一個運算子的右邊,則表示其為「之前」。 如果運算子位於另一個運算子的左邊,則表示其為「之後」。

  • 在 SSMS 中,反白顯示查詢,然後從工具列選取 [顯示預計執行計畫],或使用 Ctrl+L
  • 在 Azure Data Studio 中,反白顯示查詢,然後選取 [說明]。 然後考慮下列案例,以判斷是否發生下推。

下列每個範例都包含 SSMS 和 Azure Data Studio 的輸出。

篩選述詞下推 (透過執行計畫檢視)

請考慮下列查詢,其使用 WHERE 子句中的篩選述詞:

SELECT *
FROM [Person].[BusinessEntity] AS be
WHERE be.BusinessEntityID = 17907;

如果發生篩選述詞的下推,篩選運算子位於外部運算子之前。 當篩選運算子在外部運算子之前,篩選會在從外部資料來源中選取之前發生,表示篩選述詞已下推。

使用篩選述詞下推 (透過執行計畫檢視)

啟用追蹤旗標 6408 後,會在預估執行計畫輸出中看到其他資訊。 輸出會根據 SSMS 和 Azure Data Studio 而有所不同。

在 SSMS 中,遠端查詢計畫會顯示在預估執行計畫中做為 Query 2 (sp_execute_memo_node_1),並對應至查詢 1 中的遠端查詢運算子。 例如:

A screenshot of an execution plan with filter predicate pushdown from SSMS.

在 Azure Data Studio 中,遠端查詢執行會表示為單一查詢計畫。 例如:

A screenshot of an execution plan with filter predicate pushdown from Azure Data Studio.

沒有篩選述詞下推 (透過執行計畫檢視)

如果篩選述詞下推未發生,篩選將會發生在外部運算子之後。

SSMS 的預估執行計畫:

A screenshot of an execution plan without filter predicate pushdown from SSMS.

Azure Data Studio 的預估執行計畫:

A screenshot of an execution plan without filter predicate pushdown from Azure Data Studio.

JOIN 下推

請考慮下列查詢,此查詢會針對相同外部資料來源上的兩個外部資料表使用 JOIN 運算子:

SELECT be.BusinessEntityID, bea.AddressID
FROM [Person].[BusinessEntity] AS be
INNER JOIN [Person].[BusinessEntityAddress] AS bea
ON be.BusinessEntityID = bea.BusinessEntityID;

如果 JOIN 向下推送至外部資料來源,Join 運算子將會在外部運算子之前。 在此範例中,[BusinessEntity][BusinessEntityAddress] 都是外部表格。

透過 JOIN 下推 (檢視執行計畫)

SSMS 的預估執行計畫:

A screenshot of an execution plan with join pushdown from SSMS.

Azure Data Studio 的預估執行計畫:

A screenshot of an execution plan with join pushdown from Azure Data Studio.

沒有加入下推 (檢視執行計畫)

如果未將 JOIN 下推至外部資料來源,Join 運算子將會在外部運算子之後。 在 SSMS 中,外部運算子位於 sp_execute_memo_node 的查詢計畫中,其位於查詢 1 中的遠端查詢運算子中。 在 Azure Data Studio 中,Join 運算子位於外部運算子之後。

SSMS 的預估執行計畫:

A screenshot of an execution plan without join pushdown from SSMS.

Azure Data Studio 的預估執行計畫:

A screenshot of an execution plan without join pushdown from Azure Data Studio.

彙總下推 (檢視執行計畫)

考慮使用彙總函式的下列查詢:

SELECT SUM([Quantity]) as Quant
FROM [AdventureWorks2022].[Production].[ProductInventory];

使用彙總下推 (檢視執行計畫)

如果發生彙總下推,彙總運算子會在外部運算子之前。 當彙總運算子在外部運算子之前,彙總會在從外部資料來源中選取之前發生,表示彙總已下推。

SSMS 的預估執行計畫:

A screenshot of an execution plan with aggregate pushdown from SSMS.

Azure Data Studio 的預估執行計畫:

A screenshot of an execution plan with aggregate pushdown from Azure Data Studio.

沒有彙總下推 (檢視執行計畫)

如果彙總下推未發生,彙總運算子將會在外部運算子之後。

SSMS 的預估執行計畫:

A screenshot of an execution plan without aggregate pushdown from SSMS.

Azure Data Studio 的預估執行計畫:

A screenshot of an execution plan without aggregate pushdown from Azure Data Studio.

使用 DMV

在 SQL Server 2019 (15.x) 和更新版本中,sys.dm_exec_external_work DMVread_command 行會顯示傳送至外部資料來源的查詢。 這可讓您判斷是否發生下推,但不會公開執行計畫。 檢視遠程查詢不需要 TF6408。

注意

針對 Hadoop 和 Azure 儲存體,read_command 一律會傳回 NULL

您可以執行下列查詢,並使用 start_time/end_timeread_command 來識別正在調查的查詢:

SELECT execution_id, start_time, end_time, read_command
FROM sys.dm_exec_external_work
ORDER BY execution_id desc;

注意

sys.dm_exec_external_work 方法的其中一個限制是 DMV 中的 read_command 欄位限制為 4000 個字元。 如果查詢足夠長,read_command 可能會在看到 read_command 中的 WHERE/JOIN/aggregation 函式之前被截斷。

篩選述詞下推 (使用 DMV 檢視)

請考慮先前篩選述詞範例中使用的查詢:

SELECT *
FROM [Person].[BusinessEntity] be
WHERE be.BusinessEntityID = 17907;

使用篩選下推 (使用 DMV 檢視)

您可以藉由檢查 DMV 中的 read_command 來判斷是否發生篩選述詞下推。 在這裡,您會看到類似此範例的內容:

SELECT [T1_1].[BusinessEntityID] AS [BusinessEntityID], [T1_1].[rowguid] AS [rowguid], 
  [T1_1].[ModifiedDate] AS [ModifiedDate] FROM 
  (SELECT [T2_1].[BusinessEntityID] AS [BusinessEntityID], [T2_1].[rowguid] AS [rowguid], 
    [T2_1].[ModifiedDate] AS [ModifiedDate] 
FROM [AdventureWorks2022].[Person].[BusinessEntity] AS T2_1 
WHERE ([T2_1].[BusinessEntityID] = CAST ((17907) AS INT))) AS T1_1;

WHERE 子句位於傳送至外部資料來源的命令中,這表示篩選述詞是在外部資料來源進行評估。 篩選資料集發生在外部資料來源,而且 PolyBase 只會擷取篩選的資料集。

沒有篩選下推 (使用 DMV 檢視)

如果未發生下推,會看到類似如下內容:

SELECT "BusinessEntityID","rowguid","ModifiedDate" FROM "AdventureWorks2022"."Person"."BusinessEntity"

命令中沒有 WHERE 子句傳送至外部資料來源,因此不會下推篩選述詞。 在 PolyBase 擷取資料集之後,整個資料集的篩選發生在 SQL Server 端。

JOIN 下推 (使用 DMV 檢視)

請考慮先前 JOIN 範例中使用的查詢:

SELECT be.BusinessEntityID, bea.AddressID
FROM [Person].[BusinessEntity] be
INNER JOIN [Person].[BusinessEntityAddress] bea ON be.BusinessEntityID = bea.BusinessEntityID;

使用 JOIN 下推 (使用 DMV 檢視)

如果 JOIN 下推至外部資料來源,會看到類似如下內容:

SELECT [T1_1].[BusinessEntityID] AS [BusinessEntityID], [T1_1].[AddressID] AS [AddressID] 
FROM (SELECT [T2_2].[BusinessEntityID] AS [BusinessEntityID], [T2_1].[AddressID] AS [AddressID] 
FROM [AdventureWorks2022].[Person].[BusinessEntityAddress] AS T2_1 
INNER JOIN  [AdventureWorks2022].[Person].[BusinessEntity] AS T2_2  
ON ([T2_1].[BusinessEntityID] = [T2_2].[BusinessEntityID])) AS T1_1;

JOIN 子句位於傳送至外部資料來源的命令中,因此 JOIN 會被下推。 資料集上的聯結發生在外部資料來源,只有符合聯結條件的資料集才會由 PolyBase 擷取。

沒有 JOIN 下推 (使用 DMV 檢視)

如果未發生 JOIN 下推,會看到針對外部資料來源執行兩個不同的查詢:

SELECT [T1_1].[BusinessEntityID] AS [BusinessEntityID], [T1_1].[AddressID] AS [AddressID] 
FROM [AdventureWorks2022].[Person].[BusinessEntityAddress] AS T1_1;

SELECT [T1_1].[BusinessEntityID] AS [BusinessEntityID] FROM [AdventureWorks2022].[Person].[BusinessEntity] AS T1_1;

在 PolyBase 擷取這兩個資料集之後,聯結兩個資料集發生在 SQL Server 端。

彙總下推 (使用 DMV 檢視)

考慮使用彙總函式的下列查詢:

SELECT SUM([Quantity]) as Quant
FROM [AdventureWorks2022].[Production].[ProductInventory];

使用彙總下推 (使用 DMV 檢視)

如果發生彙總下推,會看到 read_command 中的彙總函式。 例如:

SELECT [T1_1].[col] AS [col] FROM (SELECT SUM([T2_1].[Quantity]) AS [col] 
FROM [AdventureWorks2022].[Production].[ProductInventory] AS T2_1) AS T1_1

彙總函式位於傳送至外部資料來源的命令中,因此彙總會向下推送。 彙總發生在外部資料來源,而 PolyBase 只會擷取彙總資料集。

沒有彙總下推 (使用 DMV 檢視)

如果未發生彙總下推,則不會在 read_command 中看到彙總函式。 例如:

SELECT "Quantity" FROM "AdventureWorks2022"."Production"."ProductInventory"

在 PolyBase 擷取未彙總資料集之後,彙總在 SQL Server 中執行。

下一步