ablog

不器用で落着きのない技術者のメモ

パイプライン表関数

テーブル・ファンクションは、行のコレクション(ネストした表またはVARRAY)を戻すユーザー定義のPL/SQLファンクションです。SELECT文のTABLE句の内部でテーブル・ファンクションを起動することで、データベース表のようにこのコレクションから要素を選択できます。次に例を示します。

SELECT * FROM TABLE(table_function_name(parameter_list))

(中略)
テーブル・ファンクションの実行をパラレル化でき、戻された行を中間的なステージングなしで次のプロセスに直接送ることができます。テーブル・ファンクションから戻されたコレクションに含まれる行を、パイプライン化することもできます。つまり、テーブル・ファンクションの入力の処理がすべて完了した後にバッチで戻すかわりに、生成されるたびに反復的に戻すことができます。
(中略)
スタンドアロン・ファンクションでは、CREATE FUNCTION文にPIPELINEDオプションを指定します(構文は、「CREATE FUNCTION文」を参照してください)。パッケージ・ファンクションでは、ファンクション宣言とファンクション定義の両方にPIPELINEDオプションを指定します(構文は、「ファンクションの宣言および定義」を参照してください)。

PL/SQLの最適化とチューニング

非パイプライン・テーブル・ファンクションの場合、問合せで1つの結果行が戻されるには、その前にテーブル・ファンクションから戻されるコレクション全体が構成され、サーバーに戻される必要があります。パイプライン化により、行が生成されるたびに反復的に戻すことができます。また、これにより、オブジェクト・キャッシュではコレクション全体をマテリアライズする必要がないため、テーブル・ファンクションに必要なメモリーも減少します。
(中略)
テーブル・ファンクションでのみ使用し、このファンクションがパイプラインであることを指定します。パイプライン・テーブル・ファンクションは、行を処理した直後に起動元に行を戻し、行の処理を継続します。起動元に(制御を戻さずに)行を戻すために、このファンクションでは「PIPE ROW文」を使用します。

ファンクションの宣言および定義

ライン生産方式などパイプライン的なものは様々なところに存在する。自動車の組み立てを考えてみよう。流れ作業の一工程として、エンジンのシャーシへの設置、フードの設置、車輪の設置があり、この順番で実施されるとする。ラインの各工程には、1台の組み立て中の自動車だけがある。エンジンを設置し終えた自動車は、次にフードの設置工程に移され、エンジン設置用の機械設備は次の自動車に取り掛かることができる。最初の自動車はさらに車輪設置工程に進み、2台目の自動車はフード設置工程に進み、3台目の自動車がエンジン設置工程に進んでくる。エンジン設置に20分かかり、フード設置に5分、車輪設置に10分かかるとすると、一度に1台ずつ組み立てると3台組み立てるのに105分かかる。しかし、ライン生産方式では75分で3台の組み立てが完了する。その後も20分間隔で自動車が組み立てられていく。

パイプライン処理 - Wikipedia

まとめ*1

  • 表関数は表をSELECTしたときのように複数行を返す関数。
  • 結果が全部揃うまで待つのではなくできた行から順次帰す表関数がパイプライン表関数。
  • 仕組みは自動車組立工場のライン生産方式と同じ。
  • 1人の職人が一から自動車を組立ていた時代もあるが、自動車組立工場では100台全てのシャーシにエンジンを設置し終えてからタイヤを取り付けるのではなく、できたものが次の工程に流して各工程の組立を並列で行っているため、同じ時間でたくさんの自動車を作ることができる。
  • パイプライン表関数のメリットとして全部結果ができてから返すのではなく、できた行から順次返すのでデータを溜めておくメモリが少なくてすむといった点がある。

関連

  • Oracle Database PL/SQL言語リファレンス 11gリリース2(11.2) B56260-04
  • KROWN#42793

*1:正確さよりわかりやすさ重視