データベースはシードの部分と再帰処理の部分を識別するために再帰的クエリーを構文解析します。システムは、シード コンポーネントが、再帰参照を行なわない再帰的クエリーの本体のすべてのSELECT文になるように定義します。デフォルトでは残りはすべて再帰的コンポーネントになるように定義されます。
例として次の再帰的ビュー定義を考えます。
CREATE RECURSIVE VIEW tc (source, destin, carrier, depth) AS ( SELECT f.source, f.destin, f.carrier, 0 AS depth FROM flights AS f WHERE f.source = 'Paris' UNION ALL SELECT tcq.source, f.destin, f.carrier, tc.depth+1 AS depth FROM tc tcq, flights AS f WHERE tcq.destin=f.source AND depth <= 100 UNION ALL SELECT tcq.source, r.destin, 'EuroRail', tc.depth+1 AS depth FROM tc AS tcq, trains AS r WHERE tcq.destin=r.source AND depth <= 100 UNION ALL SELECT r.source, r.destin, 'EuroRail', 0 AS depth FROM trains AS r WHERE r.source = 'Kaiserslautern');
ビュー定義のシード クエリー コンポーネントが太字テキストで強調されています。システムは残りのSQLテキストをすべて定義の再帰的コンポーネントとして扱います。
最適化ルーチンがクエリーを処理するステップを構築する方法を調べる基礎として次のビュー定義を考えます。
CREATE RECURSIVE VIEW reachable_from (destin, cost,depth) AS ( SELECT root.destin,root.cost, 0 AS depth FROM flights AS root WHERE root.source = 'paris' UNION ALL SELECT result.destin, seed.cost + result.cost, seed.depth + 1 AS newdepth FROM reachable_from AS seed, flights AS result WHERE seed.destin = result.source AND newdepth <= 20);
以下のクエリーのEXPLAINには、RootからのRETRIEVEステップが含まれています。これは、("Destin = Result.Source") AND "((Depth+1)<= 20)"の結合条件とともにResultからのプライマリ インデックス"Root.Source = 'Paris'" JOINステップを経由したものです。
EXPLAIN SELECT * FROM reachable_from;
仮定に基づいたEXPLAINレポート:
- Spool 1は、プライマリ インデックス"Root.Source = 'Paris'"を経由したRootからのRETRIEVEステップのシード クエリー用に構築されたステップの結果の計算に使われるプランです。
- 次に、シード クエリー ステップの結果をSpool 2に送ります。これには最終結果が入ります。
- クエリーの再帰的ステップは、("Destin = Result.Source") AND "((Depth+1)<= 20)"の結合条件とともに、ResultからのJOINステップ内で実行されます。
これはSpool 1をシード結果として使用し、それをflightsに結合します。
- その結合の結果のSpool 3は、次のシードとして取り扱われます。
Spool 3はSpool 1にデータを送ります。このSpool 1は再びシード クエリーステップの構築プロセスで使用されます。
Spool 1は、「Last Use」とすることによってクリアされます。
- 再帰的ステップは、結果が空になるまで繰り返し実行されます。
- Spool 2から取り出した行をSpool 4に入れると、リクエスト元に返される最終結果セットが生成されます。