適用対象: SQL Server 2016 (13.x) 以降のバージョン
プッシュダウン計算を使用すると、外部データ ソースに対するクエリのパフォーマンスが向上します。 SQL Server 2016 (13.x) 以降では、プッシュダウン計算は Hadoop の外部データ ソースで使用できました。 SQL Server 2019 (15.x) で、他の種類の外部データ ソースのプッシュダウン計算が導入されました。
Note
PolyBase プッシュダウン計算によりクエリに対するベネフィットがあるかどうかを判断するには、「外部プッシュダウンが発生した場合の確認方法」を参照してください。
プッシュダウン計算を有効にする
次の記事には、特定の種類の外部データ ソース用のプッシュダウン計算の構成に関する情報が含まれています。
- Enable pushdown computation in Hadoop (Hadoop でのプッシュダウン計算を有効にする)
- Oracle 上の外部データにアクセスするための PolyBase の構成
- Teradata 上の外部データにアクセスするための PolyBase の構成
- MongoDB 上の外部データにアクセスするための PolyBase の構成
- ODBC ジェネリック型の外部データにアクセスするための PolyBase の構成
- SQL Server 上の外部データにアクセスするための PolyBase の構成
この表には、さまざまな外部データ ソースに対するプッシュダウン計算のサポートがまとめてあります。
| データ ソース | 結合 | プロジェクション | 集計 | フィルター | Statistics |
|---|---|---|---|---|---|
| 汎用 ODBC | はい | はい | はい | はい | はい |
| Oracle | はい+ | はい | はい | はい | はい |
| SQL Server | はい | はい | はい | はい | はい |
| Teradata | はい | はい | はい | はい | はい |
| MongoDB* | いいえ | はい | あり*** | あり*** | はい |
| Hadoop | いいえ | はい | 一部** | 一部** | はい |
| Azure Blob Storage | いいえ | いいえ | いいえ | いいえ | はい |
* Azure Cosmos DB プッシュダウン サポートは MongoDB 用 Cosmos DB API 経由で有効にします。
** 「プッシュダウン計算と Hadoop プロバイダー」を参照してください。
*** SQL Server 2019 用 MongoDB ODBC コネクタの集計とフィルターのプッシュダウンサポートは、SQL Server 2019 CU18 で導入されました。
+ Oracle では結合のプッシュダウンがサポートされていますが、プッシュダウンを実現するには、結合列の統計を作成する必要がある場合があります。
Note
T-SQL 構文によってプッシュダウン計算はブロックできます。 詳細については、「プッシュダウンを防ぐ構文」を参照してください。
プッシュダウン計算と Hadoop プロバイダー
PolyBase は現在、Hortonworks Data Platform (HDP) と Cloudera Distributed Hadoop (CDH) の 2 種類の Hadoop プロバイダーをサポートしています。 プッシュダウン計算の観点から、2 つのプロバイダー間に違いはありません。
Hadoop で計算プッシュダウン機能を使用するには、ターゲット Hadoop クラスターに、HDFS、YARN、MapReduce というコア コンポーネントがあり、ジョブ履歴サーバーが有効になっている必要があります。 PolyBase から MapReduce 経由でプッシュダウン クエリを送信し、ジョブの履歴サーバーからステータスをプルします。 いずれかのコンポーネントがない場合、クエリは失敗します。
集計によっては、データが SQL Server に到達した後に実行される必要があります。 ただし、集計の一部は、Hadoop で発生します。 これは、超並列処理システムで一般的な集計の計算方法です。
Hadoop プロバイダーでは、次の集計とフィルターがサポートされます。
| 集計 | フィルター (バイナリ比較) |
|---|---|
| Count_Big | NotEqual |
| SUM | LessThan |
| Avg | LessOrEqual |
| Max | GreaterOrEqual |
| 分 | GreaterThan |
| Approx_Count_Distinct | 等しい |
| IsNot |
プッシュダウン計算の主な有益シナリオ
PolyBase プッシュダウン計算を使用すれば、計算タスクを外部データ ソースに委任できます。 これにより、SQL Server インスタンス上のワークロードが軽減されるので、パフォーマンスが大幅に向上する可能性があります。
SQL Server では、リモート コンピューティングを利用し、ネットワーク経由で送信されるデータを制限することで、結合、プロジェクション、集計、フィルターを外部データ ソースにプッシュできます。
プッシュダウンに参加する
PolyBase は、同じ外部データ ソース上の 2 つの外部テーブルを結合するときに結合演算子のプッシュダウンを容易にできるため、パフォーマンスが大幅に向上します。
外部データ ソースが結合を実行すると、データ移動の量が減り、クエリのパフォーマンスが向上します。 結合プッシュダウンを使用しない場合、SQL Server は両方のテーブルのデータをローカルに tempdb に取り込み、結合を実行する必要があります。
分散結合の場合 (ローカル テーブルを外部テーブルに結合する) 場合、フィルターが結合された外部テーブルに適用されない限り、SQL Server は外部テーブルのすべてのデータをローカルにtempdbに取り込んで結合操作を実行する必要があります。 たとえば、次のクエリでは、外部テーブル結合条件に対するフィルター処理がないため、外部テーブルからすべてのデータが読み取られます。
SELECT * FROM LocalTable L
JOIN ExternalTable E on L.id = E.id
結合では外部テーブルの E.id 列が使用されるため、その列にフィルター条件を追加すると、SQL Server によってフィルターがプッシュダウンされ、外部テーブルから読み取られる行数が減ります。
SELECT * FROM LocalTable L
JOIN ExternalTable E on L.id = E.id
WHERE E.id = 20000
行のサブセットを選択する
外部テーブルから行のサブセットを選択するクエリのパフォーマンスを改善するには、述語のプッシュダウンを使用します。
この例では、SQL Server は map-reduce ジョブを開始して、Hadoop で述語 customer.account_balance < 200000 に一致する行を取得します。 このクエリは、テーブルのすべての行をスキャンせずに完了できるため、述語の条件に合う行のみが SQL Server にコピーされます。 この方法で、残高 < 200000 の顧客数が残高 >= 200000 の顧客数と比較して少ない場合に、時間が大幅に短縮され一時的な記憶領域が少なくなります。
SELECT * FROM customer WHERE customer.account_balance < 200000;
SELECT * FROM SensorData WHERE Speed > 65;
列のサブセットを選択する
外部テーブルから列のサブセットを選択するクエリのパフォーマンスを改善するには、述語のプッシュダウンを使用します。
このクエリでは、SQL Server で map-reduce ジョブを開始し、Hadoop の区切りテキスト ファイルを前処理して、customer.name および customer.zip_code という 2 列のデータのみが SQL Server にコピーされるようにします。
SELECT customer.name, customer.zip_code
FROM customer
WHERE customer.account_balance < 200000;
基本的な式と演算子のプッシュダウン
SQL Server では、述語のプッシュダウンに対して次の基本的な式と演算子を使用できます。
- 数値、日付値、時間値の 2 項比較演算子 (
<、>、=、!=、<>、>=、<=)。 - 算術演算子 (
+、-、*、/、%)。 - 論理演算子 (
AND、OR)。 - 単項演算子 (
NOT、IS NULL、IS NOT NULL)。
演算子 BETWEEN、 NOT、 IN、および LIKE は、基本的な関係演算子を使用して、クエリ オプティマイザーが演算子式を一連のステートメントとして書き換える方法に応じて、プッシュダウンできます。
この例のクエリには、Hadoop にプッシュダウンできる述語が複数あります。 SQL Server は、map-reduce ジョブを Hadoop にプッシュして、述語 customer.account_balance <= 200000 を実行できます。
BETWEEN 92656 AND 92677 の式もまた、Hadoop にプッシュできる 2 項演算子と論理演算子とで構成されます。
内の論理customer.account_balance AND customer.zipcodeが最後の式です。
この述語の組み合わせで、map-reduce ジョブですべての WHERE 句を実行できます。
SELECT 条件を満たすデータのみが SQL Server にコピーされて戻されます。
SELECT * FROM customer
WHERE customer.account_balance <= 200000
AND customer.zipcode BETWEEN 92656 AND 92677;
プッシュダウンでサポートされている関数
SQL Server では、述語プッシュダウンに対して次の関数を使用できます。
文字列関数:
CONCATDATALENGTHLENLIKELOWERLTRIMRTRIMSUBSTRINGUPPER
数学関数:
ABSACOSASINATANCEILINGCOSEXPFLOORPOWERSIGNSINSQRTTAN
基本的な機能:
COALESCE*NULLIF
* COLLATE とともに使用すると、一部のシナリオでプッシュダウンを防ぐことができます。 詳細については、「照合順序の競合」を参照してください。
日付と時刻の関数:
DATEADDDATEDIFFDATEPART
プッシュダウンを防止する構文
次の T-SQL 関数または構文項目は、プッシュダウン計算を妨げるものです。
AT TIME ZONECONCAT_WSTRANSLATERANDCHECKSUMBINARY_CHECKSUMHASHBYTESISJSONJSON_VALUEJSON_QUERYJSON_MODIFYNEWIDSTRING_ESCAPECOMPRESSDECOMPRESSGREATESTLEASTPARSE
FORMAT および TRIM 構文のプッシュダウン サポートは、SQL Server 2019 (15.x) CU10 で導入されました。
変数を含むフィルター句
フィルター句で変数を指定した場合、既定では、SQL Server はフィルター句をプッシュダウンしません。 たとえば、次のクエリはフィルター句をプッシュダウンしません。
DECLARE @BusinessEntityID INT
SELECT * FROM [Person].[BusinessEntity]
WHERE BusinessEntityID = @BusinessEntityID;
変数のプッシュダウンを有効にするには、次のいずれかの方法を使用してクエリ オプティマイザーの修正プログラム機能を有効にします。
- インスタンス レベル: インスタンスのスタートアップ パラメーターとしてトレース フラグ 4199 を有効にします。
-
データベース レベル: PolyBase 外部オブジェクトを持つデータベースのコンテキストで、
ALTER DATABASE SCOPED CONFIGURATION SET QUERY_OPTIMIZER_HOTFIXES = ON実行します。 -
クエリ レベル: クエリ ヒントの
OPTION (QUERYTRACEON 4199)またはOPTION (USE HINT ('ENABLE_QUERY_OPTIMIZER_HOTFIXES'))を使用します。
この制限は、 sp_executesql の実行と、フィルター句内の一部の関数に適用されます。
SQL Server 2019 CU5 では、最初に変数をプッシュダウンする機能が導入されました。
詳細については、「 sp_executesql」を参照してください。
照合順序の競合
照合順序が異なるデータではプッシュダウンが機能しない場合があります。
COLLATE のような演算子が、結果に干渉する可能性もあります。 SQL Server では、等しい照合順序またはバイナリ照合順序がサポートされています。 詳細については、「外部プッシュダウンが発生した場合の確認方法」を参照してください。
Parquet ファイルのプッシュダウン
SQL Server 2022 (16.x) 以降、PolyBase では Parquet ファイルのサポートが導入されました。 SQL Server では、Parquet を使用してプッシュダウンを実行するときに、行と列の両方の削除を実行できます。
サポートされている外部データ ソース
Parquet プッシュダウンは、次の外部データ ソースでサポートされています。
- S3 互換オブジェクト ストレージ
- Azure Blob Storage
- Azure Data Lake Storage Gen2
構成の詳細については、以下を参照してください。
- S3 互換オブジェクト ストレージの外部データにアクセスするように PolyBase を構成する
- PolyBase を使用して S3 互換オブジェクト ストレージ内の Parquet ファイルを仮想化する
プッシュダウン操作
SQL Server では、Parquet ファイルを使用して次の操作をプッシュダウンできます。
- 数値、日付値、時間値のバイナリ比較演算子 (>、>=、<=、<)。
- 比較演算子の組み合わせ (> AND <、>= AND <、> AND <=、<= AND >=)。
- リスト フィルター (col1 = val1 OR col1 = val2 OR vol1 = val3) の形式。
- 列に対して IS NOT NULL を適用する。
これらの項目により、Parquet ファイルのプッシュダウンが防止されます。
- 仮想列
- 列の比較。
- パラメーター型変換。
サポートされているデータ型
- bit
- tinyint
- smallint
- bigint
- real
- float
- varchar (Bin2Collation、CodePageConversion、BinCollation)
- nvarchar (Bin2Collation, BinCollation)
- バイナリ
- datetime2 (既定および 7 桁の有効桁数)
- date
- time (既定および 7 桁の有効桁数)
- 数値 *
* パラメーターの小数点以下桁数が列の小数点以下桁数と一致する場合、またはパラメーターが明示的に 10 進数にキャストされる場合にサポートされます。
Parquet プッシュダウンを防ぐデータ型
- money
- smallmoney
- datetime
- smalldatetime
フォルダー構造を使用したパーティションの削除
PolyBase では、パーティションの削除にフォルダー構造を使用できるため、クエリ中にスキャンされるデータの量を減らすことができます。 Parquet ファイルを階層フォルダー (年、月、その他のパーティション キーなど) に整理する場合、PolyBase では、クエリ述語と一致しないフォルダー全体をスキップできます。
たとえば、データを次のように構造化する場合は、次のようになります。
/data/year=2024/month=01/*.parquet
/data/year=2024/month=02/*.parquet
/data/year=2025/month=01/*.parquet
OPENROWSETまたは外部テーブルの場所でワイルドカードを使用して、特定のパーティションに対してクエリを実行できます。
-- Query only January 2025 data
SELECT *
FROM OPENROWSET(
BULK '/data/year=2025/month=01/*.parquet',
DATA_SOURCE = 's3_ds',
FORMAT = 'PARQUET'
) AS [data];
動的フォルダーを削除するには、より広範なフォルダー パスを照会し、 filepath() 述語を使用して実行時にパーティションを削除します。
SELECT
r.filepath(1) AS [year],
r.filepath(2) AS [month],
COUNT_BIG(*) AS [rows]
FROM OPENROWSET(
BULK '/data/year=*/month=*/*.parquet',
DATA_SOURCE = 's3_ds',
FORMAT = 'PARQUET'
) WITH (
customer_id INT,
amount DECIMAL(10, 2)
) AS [r]
WHERE
r.filepath(1) = '2025'
AND r.filepath(2) = '01'
GROUP BY
r.filepath(1),
r.filepath(2);
この方法では、フォルダー レベルのパーティションの削除と Parquet ファイル レベルのプッシュダウンを組み合わせて、最適なクエリ パフォーマンスを実現します。 フォルダー パターンを使用した Parquet ファイルのクエリの完全なチュートリアルについては、PolyBase を使用した S3 互換オブジェクト ストレージでの Parquet ファイルの仮想化に関するページを参照してください。
例
プッシュダウンを強制する
SELECT * FROM [dbo].[SensorData]
WHERE Speed > 65
OPTION (FORCE EXTERNALPUSHDOWN);
プッシュダウンを無効にする
SELECT * FROM [dbo].[SensorData]
WHERE Speed > 65
OPTION (DISABLE EXTERNALPUSHDOWN);