この項では、空間問合せと空間結合の解決のために使用する空間レイヤーの構造について説明します。
Spatial and Graphでは、「問合せモデル」で説明したとおり、空間問合せおよび空間結合を解決するために、1次フィルタ処理と2次フィルタ処理を含む2層問合せモデルを使用します。2層とは、問合せの解決のために2種類の別々の処理が実行されることを指します。両方の処理が実行されると、完全一致の結果セットが戻されます。
問合せ内の空間表に空間索引が定義されている場合、その表の名前にデータベース・リンク(dblink)名を追加することはできません。
この項には次のトピックも含まれます。
空間Rツリー索引では、各ジオメトリが最小境界矩形(MBR)で表現されます(「Rツリー索引」を参照)。図5-1のような、複数のオブジェクトを含むレイヤーについて考えてみます。各オブジェクトには、ジオメトリ名が付いており(線ストリングにはgeom_1、4面のポリゴンにはgeom_2、三角形ポリゴンにはgeom_3、楕円にはgeom_4)、各オブジェクトのMBRは破線で表されています。
一般的な空間問合せでは、問合せウィンドウ(定義された範囲またはウィンドウ)の内部に位置するすべてのオブジェクトが要求されます。動的問合せウィンドウとは、データベース内には定義されず、使用前に定義が必要な矩形領域を指します。図5-2に、図5-1と同じジオメトリに、太い点線のボックスで表されている問合せウィンドウを追加したものを示します。
図5-2で、問合せウィンドウは、ジオメトリgeom_1およびgeom_2の一部と、geom_3のMBRの一部を覆っていますが、実際のgeom_3ジオメトリは覆っていません。問合せウィンドウは、geom_4ジオメトリまたはそのMBRを覆っていません。
SDO_FILTER演算子(「空間演算子」を参照)は、Spatial and Graphの問合せ処理モデルに含まれる2段階の処理のうち、1次フィルタ部分を実行します。1次フィルタは、候補オブジェクトの組合せの集合が相互作用するかどうかを判断するためにのみ索引データを使用します。具体的には、1次フィルタは、候補オブジェクト自体が相互作用するかどうかではなく、候補オブジェクトのMBRが相互作用するかどうかを確認します。SDO_FILTER演算子の構文は、次のとおりです。
SDO_FILTER(geometry1 SDO_GEOMETRY, geometry2 SDO_GEOMETRY, param VARCHAR2)
前の構文では:
geometry1
は、表のSDO_GEOMETRY型の列です。この列は、空間索引付けされている必要があります。
geometry2
は、SDO_GEOMETRY型のオブジェクトです。このオブジェクトは、表から取り出される場合とそうでない場合があります。表から取り出される場合は、空間索引付けされている場合とされていない場合があります。
param
は、VARCHAR2型のオプションの文字列です。min_resolution
キーワードとmax_resolution
キーワードのいずれか、または両方を指定できます。
次の例では、1次フィルタ処理のみを実行します(2次フィルタ処理は実行しません)。この例では、図5-2に示すジオメトリのうち、MBRが問合せウィンドウと交差するすべてのジオメトリが戻されます。次の例の結果は、ジオメトリgeom_1、geom_2、geom_3です。
次の例では、問合せウィンドウを表に挿入せずに1次フィルタ処理を実行します。そのウィンドウはメモリー内で索引付けされるため、パフォーマンスが大幅に向上します。
例5-2 一時問合せウィンドウを使用した1次フィルタ
SELECT A.Feature_ID FROM TARGET A WHERE sdo_filter(A.shape, SDO_geometry(2003,NULL,NULL, SDO_elem_info_array(1,1003,3), SDO_ordinate_array(x1,y1, x2,y2)) ) = 'TRUE';
次の例では、(x1,y1)
および(x2,y2)
は、問合せウィンドウの左下および右上の角です。
次の例では、問合せ自体にウィンドウ・パラメータを指定するのではなく、SDO_GEOMETRY型の一時的なインスタンスが、問合せウィンドウ用に構成されます。
例5-3 問合せウィンドウの一時的なインスタンスを使用した1次フィルタ
SELECT A.Feature_ID FROM TARGET A WHERE sdo_filter(A.shape, :theWindow) = 'TRUE';
次の例では、問合せウィンドウが、WINS_1というIDを持つ表WINDOWSに挿入されたとします。
例5-4 ストアド問合せウィンドウを使用した1次フィルタ
SELECT A.Feature_ID FROM TARGET A, WINDOWS B WHERE B.ID = 'WINS_1' AND sdo_filter(A.shape, B.shape) = 'TRUE';
B.SHAPE列が空間索引付けされていない場合、SDO_FILTER演算子は、問合せウィンドウをメモリー内で索引付けするため、高いパフォーマンスを実現します。
SDO_RELATE演算子(「空間演算子」を参照)は、1次フィルタおよび2次フィルタの両方の処理を、問合せ処理時に実行します。2次フィルタは、実際に相互作用する候補オブジェクトのみが選択されていることを確認します。この演算子は、2次元のデータに空間索引が作成されている場合にのみ使用できます。SDO_RELATE演算子の構文は次のとおりです。
SDO_RELATE(geometry1 SDO_GEOMETRY, geometry2 SDO_GEOMETRY, param VARCHAR2)
前の構文では:
geometry1
は、表のSDO_GEOMETRY型の列です。この列は、空間索引付けされている必要があります。
geometry2
は、SDO_GEOMETRY型のオブジェクトです。このオブジェクトは、表から取り出される場合とそうでない場合があります。表から取り出される場合は、空間索引付けされている場合とされていない場合があります。
param
は、引用符で囲まれた文字列で、mask
キーワードと有効なマスク値を持ちます。オプションで、min_resolution
キーワードまたはmax_resolution
キーワード(あるいはその両方)も設定されます。詳細は、「空間演算子」のSDO_RELATE演算子の説明を参照してください。
次の例では、1次フィルタおよび2次フィルタの両方の処理を実行します。この例では、図5-2に示すジオメトリのうち、問合せウィンドウ内に位置する、または部分的に重なるすべてのジオメトリが戻されます。これらの例の結果は、オブジェクトgeom_1およびgeom_2です。
次の例では、問合せウィンドウを表に挿入せずに、1次フィルタおよび2次フィルタの両方の処理を実行します。そのウィンドウはメモリー内で索引付けされるため、パフォーマンスが大幅に向上します。
例5-5 一時問合せウィンドウを使用した2次フィルタ
SELECT A.Feature_ID FROM TARGET A WHERE sdo_relate(A.shape, SDO_geometry(2003,NULL,NULL, SDO_elem_info_array(1,1003,3), SDO_ordinate_array(x1,y1, x2,y2)), 'mask=anyinteract') = 'TRUE';
次の例では、(x1,y1)
および(x2,y2)
は、問合せウィンドウの左下および右上の角です。
次の例では、問合せウィンドウが、WINS_1というID値を持つ表WINDOWSに挿入されたとします。
例5-6 ストアド問合せウィンドウを使用した2次フィルタ
SELECT A.Feature_ID FROM TARGET A, WINDOWS B WHERE B.ID = 'WINS_1' AND sdo_relate(A.shape, B.shape, 'mask=anyinteract') = 'TRUE';
B.SHAPE列が空間索引付けされていない場合、SDO_RELATE演算子は、問合せウィンドウをメモリー内で索引付けするため、高いパフォーマンスを実現します。
SDO_WITHIN_DISTANCE演算子(「空間演算子」を参照)は、参照オブジェクトからn 距離単位内に、表内のオブジェクトの集合があるかどうかを判断するために使用されます。この演算子は、2次元のデータに空間索引が作成されている場合にのみ使用できます。参照オブジェクトは、SDO_GEOMETRYの一時的または永続的なインスタンス(一時問合せウィンドウやデータベースに格納された永続的ジオメトリなど)です。演算子の構文は次のとおりです。
SDO_WITHIN_DISTANCE(geometry1 SDO_GEOMETRY, aGeom SDO_GEOMETRY, params VARCHAR2);
前の構文では:
geometry1
は、表のSDO_GEOMETRY型の列です。この列は、空間索引付けされている必要があります。
aGeom
は、SDO_GEOMETRY型のインスタンスです。
params
は、演算子の動作を判断する、キーワードの値のペアを引用符で囲んだ文字列です。パラメータ・リストの詳細は、「空間演算子」のSDO_WITHIN_DISTANCE演算子を参照してください。
次の例では、問合せウィンドウから1.35距離単位内にあるオブジェクトを選択します。
SELECT A.Feature_ID FROM TARGET A WHERE SDO_WITHIN_DISTANCE( A.shape, :theWindow, 'distance=1.35') = 'TRUE';
距離単位は、使用しているジオメトリ座標系に基づきます。測地座標系を使用する場合、単位はmです。座標系を使用しない場合、単位は格納されたデータの場合と同じです。
SDO_WITHIN_DISTANCE演算子は、空間結合の実行に適していません。「海岸線から10距離単位以内にあるすべての駐車場(parks)を検索」のような問合せは、COASTLINES表およびPARKS表の索引ベースの空間結合として処理されません。かわりに、それぞれのCOASTLINESインスタンスが順番にPARKS表に対してバッファ、索引付けおよび評価される参照オブジェクトになるネステッド・ループ問合せとして処理されます。このようにSDO_WITHIN_DISTANCE演算子は、COASTLINES表にn 行がある場合にn 回実行されます。
非測地データの場合、レイヤーのすべてのジオメトリのバッファリングが必要な空間結合を実行する、効率的な方法があります。この方法では、SDO_WITHIN_DISTANCE演算子は使用しません。まず、新しい表COSINE_BUFSを次のように作成します。
CREATE TABLE cosine_bufs UNRECOVERABLE AS SELECT SDO_BUFFER (A.SHAPE, B.DIMINFO, 1.35) FROM COSINE A, USER_SDO_GEOM_METADATA B WHERE TABLE_NAME='COSINES' AND COLUMN_NAME='SHAPE';
次に、COSINE_BUFSのSHAPE列に空間索引を作成します。これによって、次の問合せを実行できます。
SELECT /*+ ordered */ a.gid, b.gid FROM TABLE(SDO_JOIN('PARKS', 'SHAPE', 'COSINE_BUFS', 'SHAPE', 'mask=ANYINTERACT')) c, parks a, cosine_bufs b WHERE c.rowid1 = a.rowid AND c.rowid2 = b.rowid;
SDO_NN演算子(「空間演算子」を参照)は、最も近くにあるジオメトリを識別するために使用します。この演算子は、2次元のデータに空間索引が作成されている場合にのみ使用できます。演算子の構文は次のとおりです。
SDO_NN(geometry1 SDO_GEOMETRY, geometry2 SDO_GEOMETRY, param VARCHAR2 [, number NUMBER]);
前の構文では:
geometry1
は、表のSDO_GEOMETRY型の列です。この列は、空間索引付けされている必要があります。
geometry2
は、SDO_GEOMETRY型のインスタンスです。
param
は、キーワードと値のペアを引用符で囲んだ文字列で、近くにあるジオメトリをいくつ戻すかといった、演算子の動作を決定できます。このパラメータの詳細は、「空間演算子」のSDO_NN演算子を参照してください。
number
は、SDO_NN_DISTANCEのコールで使用される数と同じ数です。これは、SDO_NN_DISTANCE補助演算子がSDO_NNのコールに含まれている場合にのみ使用します。このパラメータの詳細は、「空間演算子」のSDO_NN演算子を参照してください。
次の例では、COLA_MARKETS表のSHAPE列から、指定した点(10,7)に最も近い2つのオブジェクトを検索します。(SELECT文のオプティマイザ・ヒントの使用方法は、「空間演算子」のSDO_NN演算子の「使用上の注意」を参照してください。)
SELECT /*+ INDEX(cola_markets cola_spatial_idx) */ c.mkt_id, c.name FROM cola_markets c WHERE SDO_NN(c.shape, SDO_geometry(2001, NULL, SDO_point_type(10,7,NULL), NULL, NULL), 'sdo_num_res=2') = 'TRUE';
空間結合は、条件で空間演算子を使用することを除いて、通常の結合と同じです。Spatial and Graphでは、あるレイヤーのすべてのジオメトリと別のレイヤーのすべてのジオメトリを比較する場合、空間結合に領域が必要です。これは、単一のジオメトリとレイヤーのすべてのジオメトリを比較する問合せウィンドウとは異なります。
空間結合を使用すると、「国立公園を横切る高速道路はどれか?」のような質問に対する回答を得ることができます。
次の表構造で、この例の結合の実行方法を示します。
PARKS( GID VARCHAR2(32), SHAPE SDO_GEOMETRY) HIGHWAYS( GID VARCHAR2(32), SHAPE SDO_GEOMETRY)
空間結合を実行するには、SDO_JOIN演算子を使用します(「空間演算子」を参照)。次の空間結合問合せでは、高速道路と公園が交差する場所の高速道路と公園のGID列の値を表示するために、1次フィルタ処理のみ('mask=FILTER'
)が実行されるため、次のようなおおまかな結果のみが戻されます。
SELECT /*+ ordered */ a.gid, b.gid FROM TABLE(SDO_JOIN('PARKS', 'SHAPE', 'HIGHWAYS', 'SHAPE', 'mask=FILTER')) c, parks a, highways b WHERE c.rowid1 = a.rowid AND c.rowid2 = b.rowid;
次の空間結合問合せは、前述の例と同じ情報を要求しますが、1次と2次の両方のフィルタ処理('mask=ANYINTERACT'
)を実行するため、正確な結果を戻します。
SELECT /*+ ordered */ a.gid, b.gid FROM TABLE(SDO_JOIN('PARKS', 'SHAPE', 'HIGHWAYS', 'SHAPE', 'mask=ANYINTERACT')) c, parks a, highways b WHERE c.rowid1 = a.rowid AND c.rowid2 = b.rowid;
空間問合せの要素には、理論上、次の次元があります。
実表ジオメトリ(空間演算子形式のgeometry1
)は、2次元、3次元またはそれ以上の次元になる可能性があります。
実表に作成される空間索引(geometry1
)は、2次元または3次元になる可能性があります。
問合せウィンドウ(空間演算子形式のgeometry2
)は、2次元、3次元またはそれ以上の次元になる可能性があります。
これらの3つの要素における次元の組合せには、サポートされるものとされないものがあります。表5-1に、2次元および3次元の組合せによる結果を示します。
表5-1 データおよび索引の次元と問合せサポート
実表(geometry1)の次元 | 空間索引の次元 | 問合せウィンドウ(geometry2)の次元 | 問合せ結果 |
---|---|---|---|
2次元 |
2次元 |
2次元 |
2次元問合せが実行されます。 |
2次元 |
2次元 |
3次元 |
問合せウィンドウのSDO_GTYPE値が適切で、3008未満の場合にサポートされます。 |
2次元 |
3次元 |
2次元 |
非サポート: 2次元データで3次元索引は許可されません。 |
2次元 |
3次元 |
3次元 |
非サポート: 2次元データで3次元索引は許可されません。 |
3次元 |
2次元 |
2次元 |
基となる各ジオメトリで3番目の(Z)次元が無視され、2次元問合せが実行されます。 |
3次元 |
2次元 |
3次元 |
問合せウィンドウのSDO_GTYPE値が適切で、3008未満の場合にサポートされます。 |
3次元 |
3次元 |
2次元 |
2次元問合せウィンドウが、0個のZ値を持つ3次元ウィンドウに変換され、3次元問合せが実行されます。 |
3次元 |
3次元 |
3次元 |
3次元問合せが実行されます。 |