書式
SDO_JOIN(table_name1, column_name1, table_name2, column_name2, params,preserve_join_order, table1_partition, table2_partition) RETURN SDO_ROWIDSET;
説明
位相関係に基づいて空間結合を実行します。
キーワードおよびパラメータ
値 | 説明 |
---|---|
table_name1 |
空間結合操作で使用される最初の表の名前を指定します。この表には、SDO_GEOMETRY型の列が含まれている必要があります。データ型はVARCHAR2です。 |
column_name1 |
|
table_name2 |
空間結合操作で使用される2つ目の表の名前を指定します。( |
column_name2 |
|
params |
キーワードおよび値のオプションのパラメータ文字列です。 |
preserve_join_order |
演算子の処理中に結合順序が保持されることが保証されている場合に指定するオプションのパラメータです。この値が |
table1_partition |
|
table2_partition |
|
戻り値
SDO_JOINは、SDO_ROWIDSETのオブジェクトを戻します。このオブジェクトは、SDO_ROWIDPAIRのオブジェクトの表で構成されます。Oracle Spatial and Graphは、SDO_ROWIDSET型を次のとおり定義します。
CREATE TYPE sdo_rowidset as TABLE OF sdo_rowidpair;
Oracle Spatial and Graphは、SDO_ROWIDPAIRオブジェクト型を次のとおり定義します。
CREATE TYPE sdo_rowidpair AS OBJECT (rowid1 VARCHAR2(24), rowid2 VARCHAR2(24));
SDO_ROWIDPAIRの定義では、rowid1
はtable_name1
のROWIDを示し、rowid2
はtable_name2
のROWIDを示します。
使用上の注意
厳密には、SDO_JOINは演算子ではなくテーブル・ファンクションです。(テーブル・ファンクションについては、『Oracle Database PL/SQL言語リファレンス』を参照してください。)ただし、使用方法が演算子に類似し、他のファンクションおよびプロシージャと同じパッケージに同梱されていないため、空間演算子の章で説明しています。
このテーブル・ファンクションは、全表結合を実行する必要がある場合に使用することをお薦めします。
column_name1
およびcolumn_name2
内のジオメトリのSRID(座標系)値および次元数は、すべて同じである必要があります。
パフォーマンスを向上させるには、/*+ ORDERED */
オプティマイザ・ヒントを使用し、FROM句の最初にSDO_JOINテーブル・ファンクションを指定します。
表がバージョン対応(Workspace Manager機能を使用)である場合は、Workspace Managerにより作成された<table_name>
_LT
表を指定する必要があります。たとえば、COLA_MARKETS表がバージョン対応の場合、その表で空間結合の操作を行うには、SDO_JOINテーブル・ファンクションを使用して、COLA_MARKETS_LT (COLA_MARKETSではなく)を指定します。(ただし、その他すべての空間ファンクション、空間プロシージャおよび空間演算子には、<table_name>
_LT
名は使用できません。)
表18-3に、params
パラメータのキーワードを示します。
表18-3 SDO_JOIN演算子のparamsキーワード
キーワード | 説明 |
---|---|
mask |
空間結合の位相関係を指定します。有効な値は、'mask=<value>'です。<value>は、SDO_RELATE演算子に有効な1つ以上のマスク値( このパラメータがNULLであるか、または空の文字列を含む場合、 |
距離 |
関係チェックが実行される前に許容差(「許容差」を参照)に追加される距離値を数値で指定します。たとえば、許容差が10 mのときに |
unit |
距離値に関連付ける測定単位を指定します( |
SDO_JOINをコールする前に、セッション内で前のすべてのDML文をコミットする必要があります。コミットしない場合、「ORA-13236: R-treeの処理で内部エラーが発生しました: [SDO_Join in active txns not supported]」
というエラーが戻されます。
空間演算子での3Dサポート(計算時にすべての3次元を考慮する演算子または考慮しない演算子)については、「3次元の空間オブジェクト」を参照してください。
自己結合の最適化
自己結合(table_name1
およびtable_name2
が同じ表を指定)を実行する場合、自己結合を最適化することでパフォーマンスを向上できます。
マスク(ANYINTERACT
など)または距離を指定せずにSDO_JOINをコールすると、結合される2つのジオメトリ列の索引構造のみが比較されます。これで、相互に作用するジオメトリのペアを簡単に識別することができます。マスクまたは距離を指定してSDO_JOINをコールすると、相互に作用するジオメトリのペアを識別するために索引が使用された後、ジオメトリのペアが実際に相互作用しているかどうかを確認するためにジオメトリの座標も比較されます。座標の比較は、SDO_JOINの操作で最もコストの高い動作になります。
同じジオメトリ列をそれ自身と比較する自己結合では、各ジオメトリ・ペアが結果セットで2回戻されます。次に例を示します。
ID値(1,2)を持つジオメトリ・ペアの場合、そのペア(2,1)も戻されます。SDO_JOINでは、同じジオメトリ・ペアの座標が、不要であるにもかかわらず、1回ではなく2回比較されます。
同じIDペアが2回戻されます。たとえば、50,000行を持つ表では、IDペア(1,1)が2回、IDペア(2,2)が2回というように戻されます。これも不要な動作です。
自己結合でSDO_JOINをコールする場合、ジオメトリ・ペアの重複する比較や、ペアのID値が同じ座標の比較を行わないことで、このような不要な動作を回避できます。この最適化は、1次フィルタに対してのみSDO_JOINを使用し、SDO_GEOM.RELATEファンクションをコールしてジオメトリ座標を比較します。次の文では、WHERE
句の条件としてAND b.rowid < c.rowid
を追加することで最適化を行っています。
SQL> set autotrace trace explain SQL> SELECT /*+ ordered use_nl (a,b) use_nl (a,c) */ b.id, c.id FROM TABLE(sdo_join('GEOD_STATES','GEOM','GEOD_STATES','GEOM')) a, GEOD_STATES b, GEOD_STATES c WHERE a.rowid1 = b.rowid AND a.rowid2 = c.rowid AND b.rowid < c.rowid AND SDO_GEOM.RELATE (b.geom, 'ANYINTERACT', c.geom, .05) = 'TRUE' Execution Plan ---------------------------------------------------------- Plan hash value: 1412731386 --------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 1124 | 12787 (1)| 00:02:34 | | 1 | NESTED LOOPS | | 1 | 1124 | 12787 (1)| 00:02:34 | | 2 | NESTED LOOPS | | 4574 | 2514K| 8206 (1)| 00:01:39 | | 3 | COLLECTION ITERATOR PICKLER FETCH| SDO_JOIN | | || | |* 4 | TABLE ACCESS BY USER ROWID | GEOD_STATES | 1 | 561 |1 (0)| 00:00:01 | |* 5 | TABLE ACCESS BY USER ROWID | GEOD_STATES | 1 | 561 |1 (0)| 00:00:01 | Predicate Information (identified by operation id): --------------------------------------------------- 4 - access(CHARTOROWID(VALUE(KOKBF$))) 5 - access(CHARTOROWID(VALUE(KOKBF$))) filter("B".ROWID<"C".ROWID AND "SDO_GEOM"."RELATE"("B"."GEOM",'ANYINTERACT',"C"."GEOM",.05)='TRUE') SQL> set autotrace off
前述の例では、AND b.rowid < c.rowid
は、WHERE
句内でSDO_GEOM.RELATEのコールの前に記述することが重要です。これにより、SDO_GEOM.RELATEファンクションの起動による不要な動作を省略できます。この例では、ORDERED
およびUSE_NL
ヒントを使用していること、および実行計画にTABLE ACCESS FULL
またはHASH JOIN
が含まれていないことに注意してください。
SDO_JOINのクロススキーマでの使用
空間表とその空間表に作成された空間索引の索引表の両方に対するSELECT権限を付与されている場合は、自分のスキーマにない索引付けされた表でSDO_JOINテーブル・ファンクションを起動できます。空間索引の索引表の名前を検索するには、USER_SDO_INDEX_METADATAビューでSDO_INDEX_TABLE列を問い合せます。たとえば、次の文では、COLA_MARKETS_IDX空間索引の索引表の名前が戻されます。
SELECT sdo_index_table FROM user_sdo_index_metadata WHERE sdo_index_name = 'COLA_SPATIAL_IDX';
ユーザーAが空間表T1 (および索引表MDRT_F9AA$)を所有し、ユーザーBが空間表T2を所有し、T1とT2両方のジオメトリを結合する必要があるとします。また、両方の表でジオメトリ列の名前がGEOMETRYであるとします。
ユーザーAまたは適切な権限を付与されたユーザーが、ユーザーAとして接続し、次の文を実行する必要があります。
GRANT select on T1 to B; GRANT select on MDRT_F9AA$ to B;
これで、ユーザーBが接続し、SDO_JOIN問合せを実行できます。次に例を示します。
SELECT COUNT(*) FROM (SELECT * FROM TABLE(SDO_JOIN('A.T1', 'GEOMETRY', 'B.T2', 'GEOMETRY', 'mask=anyinteract')) );
例
次の例では、COLA_MARKETS表をその表自体と結合し、各ジオメトリを調べてその表と空間的に相互作用する他のすべてのジオメトリを検索します。(例では、「空間データの挿入、索引付けおよび問合せの例」の定義およびデータを使用しています。)この例では、rowid1
およびrowid2
は、SDO_ROWIDPAIR型の定義内の属性名に対応しています。出力で、cola_d
(図2-1の円)がそれ自体とのみ相互作用し、他のジオメトリとは相互作用していないことに注意してください。
SELECT /*+ ordered */ a.name, b.name FROM TABLE(SDO_JOIN('COLA_MARKETS', 'SHAPE', 'COLA_MARKETS', 'SHAPE', 'mask=ANYINTERACT')) c, cola_markets a, cola_markets b WHERE c.rowid1 = a.rowid AND c.rowid2 = b.rowid ORDER BY a.name; NAME NAME -------------------------------- -------------------------------- cola_a cola_c cola_a cola_b cola_a cola_a cola_b cola_c cola_b cola_b cola_b cola_a cola_c cola_c cola_c cola_b cola_c cola_a cola_d cola_d 10 rows selected.
関連項目