外部プッシュダウンが発生した場合の確認方法

この記事では、PolyBase クエリが外部データ ソースへのプッシュダウンによるベネフィットを得られるかどうかを確認する方法について詳細に説明します。 外部プッシュダウンの詳細については、「PolyBase でのプッシュダウン計算」を参照してください。

自分のクエリは外部プッシュダウンのベネフィットを得られるか

プッシュダウン計算を使用すると、外部データ ソースに対するクエリのパフォーマンスが向上します。 特定の計算タスクは、SQL Server に送信される代わりに外部データ ソースに委任されます。 特にフィルター処理と結合のプッシュダウンでは、SQL Server インスタンスのワークロードを大幅に削減できます。

PolyBase プッシュダウン計算を使用すると、クエリのパフォーマンスを大幅に向上させることができます。 PolyBase クエリの実行速度が遅い場合、PolyBase クエリのプッシュダウンが発生しているかどうかを確認する必要があります。

実行プランでプッシュダウンを監視できるシナリオには、次の 3 種類があります。

  • フィルター述語のプッシュダウン
  • 結合のプッシュダウン
  • 集計のプッシュダウン

注意

PolyBase プッシュダウン計算を使用して外部データ ソースにプッシュダウンできるものには制限があります。

SQL Server 2019 (15.x) では、管理者が、PolyBase クエリが外部データ ソースにプッシュダウンされているかどうかを確認するために使用できる次の 2 つの新しい機能が導入されました。

この記事では、3 つのプッシュダウン シナリオごとに、これら 2 つのユース ケースの使用方法についてそれぞれ詳細に説明します。

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) として表示され、Query 1 のリモート クエリ演算子に対応します。 次に例を示します。

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

Azure Data Studio では、リモート クエリ実行が 1 つのクエリ プランとして表されます。 次に例を示します。

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 のプッシュダウン

同じ外部データ ソース上の 2 つの外部テーブルに対して JOIN 演算子を使用する次のクエリについて考えてみましょう。

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

JOIN が外部データ ソースにプッシュダウンされる場合、結合演算子は、外部演算子の前になります。 この例では、[BusinessEntity][BusinessEntityAddress] は両方とも外部テーブルです。

結合のプッシュダウンあり (実行プランを使用して表示)

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 が外部データ ソースにプッシュダウンされない場合、結合演算子は、外部演算子の後になります。 SSMS では、外部演算子は、Query 1 のリモート クエリ演算子内にある sp_execute_memo_node のクエリ プラン内にあります。 Azure Data Studio では、結合演算子は外部演算子の後にあります。

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 DMV の read_command 列に、外部データ ソースに送信されるクエリが表示されます。 これにより、プッシュダウンが発生しているかどうかを判断できますが、実行プランは公開されません。 リモート クエリを表示するために、TF6408 は必要ありません。

注意

Hadoop および Azure Storage の場合、read_command は常に NULLを返します。

次のクエリを実行し、start_time/end_time および read_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 メソッドの 1 つの制限は、DMV 内の read_command フィールドの文字数が 4,000 文字に制限されることです。 クエリが非常に長い場合、read_command に WHERE、JOIN、または集計関数が表示される前に read_command が切り捨てられることがあります。

フィルター述語のプッシュダウン (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;

結合のプッシュダウンあり (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 によって取得されました。

結合のプッシュダウンなし (DMV を使用して表示)

結合のプッシュダウンが発生していない場合、外部データ ソースに対して 2 つの異なるクエリが実行されたことが示されます。

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;

2 つのデータ セットの結合は、両方のデータ セットが 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 で実行されました。

次のステップ