Parallel Scalar UDFのサポートは妥当な機能リクエストですか?


10

スカラーUDFが全体的なシリアルプランを強制することはかなりよく文書化されています。

関数の並列実行

UDFを計算する必要があるパイプラインのポイントに入る行の数が多い場合、エンジンがそれらをプロセッサー間で単に分散できないのはなぜですか?UDF内に状態がない場合、順序は関係ありません。

UDFがブラックボックスであるため、カーソルを使用する必要があるという主張があります。反復間で一部の状態が維持されている場合、SP内でユーザーカーソルを並列化できませんが、それ以外の場合は並列化可能であるように見えます。

エンジンがUDF計算ステージだけでなく、全体の計画をシリアルにする理由を説明するための追加のポイント。

並列UDFのサポートは、要求するのに妥当な機能ですか?


1
適切な対応は、リンクへの受け入れられた回答に記載されているように、スカラーユーザー定義関数を単一列のインラインテーブル値関数として書き換えるようです。これらはビューと同じように展開され、完全に最適化されます。この観点から、あなたの質問にはまだメリットがありますか?
Pieter Geerkens、2014

1
はい、TVFの回避策で成功しました。そのような自然な構成を使用するのは間違っているように思われるので、私は尋ねました。また、新しいSQL開発者がUDFの内部について学ぶことを期待するのは実際的ではないようです。
crokusek 14

コメントの明確化。ITVFで成功するが、マルチステートメントTVFでは成功しない。
crokusek 14

回答:


17

UDFが全体的な逐次計画を強制することはかなりよく文書化されています。

十分に文書化されているかどうかはわかりません。

  • スカラーT-SQL関数は、計画のどこでも並列処理を防止します。
  • スカラーCLR関数は、データベースにアクセスしない限り、並行して実行できます。
  • 複数ステートメントのテーブル値T-SQL関数は、他の場所で並列処理を使用する可能性があるプラン内のシリアルゾーンを強制します。
  • インラインテーブル値T-SQL関数はビューのように展開されるため、直接的な影響はありません。

並列実行計画の強制および/またはCraig Freedmanの並列実行プレゼンテーションを参照してください。

UDFはブラックボックスであるため、カーソルを使用する必要があるという主張があります。

これらの主張は正しくありません。

エンジンがUDF計算ステージだけでなく、全体の計画をシリアルにする理由を説明するための追加のポイント。

私の理解では、現在の制限は純粋に特定の実装の詳細の結果です。並列処理を使用して関数を実行できなかった根本的な理由はありません。

特に、T-SQLスカラー関数は別のT-SQLコンテキスト内で実行されるため、正しい操作、調整、シャットダウン(特にエラーの場合)が大幅に複雑になります。

同様に、テーブル変数は一般的に並列読み取りをサポートします(書き込みはサポートしません)が、テーブル値関数によって公開されたテーブル変数は、実装固有の理由で並列読み取りをサポートできません。信頼できる回答を提供するには、ソースコードへのアクセス権(および詳細を共有する自由)を備えた人物が必要になると思います。

並列UDFのサポートは、要求するのに妥当な機能ですか?

もちろん、十分に強力なケースを作成できる場合。私の考えでは、関連する作業は広範囲にわたるので、あなたの提案は非常に高い基準を満たす必要があるでしょう。たとえば、インラインスカラー関数を提供するための関連する(そしてはるかに単純な)要求は優れたサポートを提供しますが、何年もの間実装されずに衰退しています。


Microsoftのペーパーを読むとよいでしょう。

... SQL Server 2017以降のリリースでT-SQLスカラー関数のパフォーマンスの問題に対処するためにMicrosoftが取ろうとしているアプローチの概要を示しています。

Froidの目標は、開発者がパフォーマンスに妥協することなくUDFとプロシージャの抽象化を使用できるようにすることです。Froidは、新しいプログラムを使用してこの目標を達成し、可能な場合は常に命令型プログラムを同等の関係代数形式に自動的に変換します。Froidは、命令コードのブロックを関係式としてモデル化し、Apply演算子を使用してそれらを体系的に単一の式に結合することで、クエリオプティマイザーが効率的なセット指向の並列クエリプランを選択できるようにします。

(強調鉱山)


インラインスカラーT-SQL関数がSQL Server 2019に実装されました


11

Paulが答えで正しく述べたように、スカラーUDFを並列処理を使用して実行できなかった根本的な理由はありません。ただし、実装の課題とは別に、強制的にシリアルにする理由はもう1つあります。Froidのポールが引用した紙は、これについての詳細な情報を提供します。

論文からの引用(セクション2.3):

現在、SQL ServerはUDFを呼び出すクエリでクエリ内並列処理を使用していません。メソッドはこの制限を緩和するように設計できますが、UDFの呼び出しごとに適切な並列度を選択するなど、追加の課題が生じます。

たとえば、図1のような他のSQLクエリを呼び出すUDFについて考えてみます。そのようなクエリ自体は並列処理を使用する可能性があるため、オプティマイザは、 UDF内で、クエリごとに並列度を決定します(呼び出しごとに異なる可能性があります)。ネストされた再帰的なUDFを使用すると、この問題の管理がさらに困難になります。

このホワイトペーパーで説明されているように、Froidのアプローチは、並列プランを作成するだけでなく、UDFを使用したクエリにさらに多くの利点をもたらします。本質的に、UDFの並列実行のリクエストを包含します。

更新: FroidがSQL Server 2019プレビューの機能として利用できるようになりました。この機能は「スカラーUDFインライン化」と呼ばれます。詳細はこちら:https : //blogs.msdn.microsoft.com/sqlserverstorageengine/2018/11/07/introducing-scalar-udf-inlining/

[開示:私はフロイド紙の共著者です]


とても良い!私が正しく理解すれば、UDFを内部でITVFに効果的に自動変換することになります。私たちはこれを数回(w / declares / if / else)実行し、素晴らしい混乱を作りました。デバッグ用の「列」もありました。
crokusek 2018

1
UDFをITVFに実際に変換するわけではありませんが、直感は正しいです。これをSQLクエリレベルで手動で行うのは、複雑なUDFの場合、非常に面倒です。Froidはリレーショナル代数ツリーでこの変換を行い、混乱を回避します:)
Karthik

@Karthikは、dba.stackexchange.com / questions / 202211 /…を見てください。私が説明したFroidのは場合に実行するために起こっているかを知ることは本当にたい
ローマPekarを

@Roman私はあなたの質問にコメントしました。
Karthik

1
@Karthik、フロイド紙で行った作業と、スカラーUDFのユーザビリティを向上させるためのあなた(およびグループ)の取り組みに
感謝します
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.