ヘッダーをスキップ
Oracle® Spatial開発者ガイド
11gリリース2 (11.2)
B72087-03
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次
索引へ移動
索引

前
 
次
 

5 空間データの索引付けおよび問合せ

空間データを使用した問合せのパフォーマンスを向上させるには、空間データのロード(第4章を参照)が完了した後で、データに対して空間索引を作成する必要があります。この章では、次の操作を実行する方法について説明します。

5.1 空間索引の作成

効率的にデータにアクセスするには、バルク・ロードまたはトランザクション・ロードによる空間表へのデータのロードが完了した後で、表内の各ジオメトリ列に対して空間索引(空間Rツリー索引)を作成する必要があります。たとえば、次の文は、すべてのパラメータについてデフォルト値を使用して、territory_idxという空間索引を作成します。

CREATE INDEX territory_idx ON territories (territory_geom)
   INDEXTYPE IS MDSYS.SPATIAL_INDEX;

空間索引の作成のオプションの詳細は、第18章CREATE INDEX文を参照してください。

索引作成が完了しなかった場合、索引は無効になるため、DROP INDEX <index_name> [FORCE]文で削除する必要があります。

索引付けされる各ジオメトリ列内では、すべてのジオメトリのSDO_SRID値が同じである必要があります。

空間索引は、2次元、3次元または4次元のデータに作成できます。デフォルトの次元数は2ですが、3次元以上のデータの場合は、sdo_indx_dimsパラメータ・キーワードを使用して、索引を作成する次元数を指定できます。(3次元ジオメトリのサポートの詳細は、1.11項を参照してください。問合せ要素における次元の様々な組合せのサポートについては、5.2.3項を参照してください。)

Oracle Databaseの自動UNDO管理機能またはPGAメモリー管理機能のいずれかを使用していないか、あるいはこの両方を使用していない場合、設定する必要のある初期化パラメータの値については、5.1.7項を参照してください。自動UNDO管理およびPGAメモリー管理の両方は、デフォルトで有効になっており、これらを使用することをお薦めします。

CREATE INDEX文のtablespaceキーワードで指定された表領域(または、tablespaceキーワードが指定されていない場合はデフォルトの表領域)を使用すると、索引データ表、および内部計算用に作成されたいくつかの一時表の両方が保持されます。WORK_TABLESPACEを表領域として指定すると、一時表は作業表領域に格納されます。

1,000,000行を超える大規模な表では、内部ソート操作を実行する場合に一時表領域が必要です。この一時表領域のサイズは、最大値を1GBとして、100×n バイト(n は表の行数)にすることをお薦めします。

空間索引の作成に必要な領域を推定するには、SDO_TUNE.ESTIMATE_RTREE_INDEX_SIZEファンクション(第31章を参照)を使用します。

5.1.1 特定のジオメトリ・タイプへのデータの制限

空間索引の作成または再作成時、表内のすべてのジオメトリ、または後で挿入されるすべてのジオメトリを、指定したジオメトリ・タイプにすることができます。このように、データのジオメトリ・タイプを制限するには、CREATE INDEX文またはALTER INDEX REBUILD文のPARAMETERS句でlayer_gtypeキーワードを使用し、2.2.1項表2-1の「ジオメトリ・タイプ」列の値を指定します。次に、レイヤー内の空間データをポリゴンに制限する例を示します。

CREATE INDEX cola_spatial_idx
ON cola_markets(shape)
INDEXTYPE IS MDSYS.SPATIAL_INDEX
PARAMETERS ('layer_gtype=POLYGON');

表2-1のジオメトリ・タイプは、データの確認時に階層とみなされます。

  • MULTIフォームには、通常のフォームも含まれます。たとえば、'layer_gtype=MULTIPOINT'を指定すると、レイヤーには、POINTジオメトリおよびMULTIPOINTジオメトリの両方を含めることができます。

  • COLLECTIONを指定すると、レイヤーには、すべてのジオメトリ・タイプを含めることができます。

5.1.2 クロススキーマの索引作成

自分のスキーマ以外にある表に対して、空間索引を作成できます。ユーザーBが、ユーザーAのスキーマにある表T1のGEOMETRY列に空間索引を作成するとします。次に手順を示します。

  1. 権限を持つユーザー(SYSTEMなど)としてデータベースに接続し、次の文を実行します。

    GRANT create table, create sequence to B;
    
  2. 権限を持つユーザーとして接続するか、またはユーザーAとして接続して(接続をユーザーAに切り替えて)、次の文を実行します。

    GRANT select, index on A.T1 to B;
    
  3. ユーザーBで接続し、次の文を実行します。

    CREATE INDEX t1_spatial_idx on A.T1(geometry)
      INDEXTYPE IS mdsys.spatial_index;
    

5.1.3 パーティション空間索引の使用

パーティション表にはパーティション空間索引を作成できます。この項では、Oracle Spatial固有の使用上の考慮点について説明します。パーティション表およびパーティション索引の詳細は、『Oracle Database管理者ガイド』を参照してください。

パーティション空間索引には、次のメリットがあります。

  • パーティション化によってディスクI/O操作が削減されるため、長時間実行問合せの応答時間が短縮されます。

  • I/O操作が各パーティションで同時に実行されるため、同時問合せの応答時間が短縮されます。

  • パーティション・レベルでの作成および再作成操作によって、索引のメンテナンスが容易になります。

    パーティションの索引は、他のパーティションに対する問合せに影響を与えずに再作成できます。また、各ローカル索引の記憶域パラメータは、他のパーティションとは無関係に変更できます。

  • 複数のパーティションの検索にパラレル問合せが実行されます。

    並列度は、USER_INDEXESビューに表示される索引の行のDEGREE列の値(CREATE INDEXALTER INDEXまたはALTER INDEX REBUILD文のPARALLELキーワードの指定値またはデフォルト値)です。

  • マルチプロセッサ・システム環境における問合せ処理が向上します。

    マルチプロセッサ・システム環境では、パーティション化された空間索引を持つ表に対して空間演算子が使用され、問合せで複数のパーティションが検索される場合、複数のプロセッサを使用して問合せを評価できます。使用されるプロセッサの数は、並列度と、問合せの評価に使用されるパーティションの数によって決まります。

空間索引のパーティション化には、次の制限事項が適用されます。

  • 空間表のパーティション・キーは、空間列ではなく、スカラー値である必要があります。

  • 基になる表では、レンジ・パーティション化のみがサポートされています。その他すべての種類のパーティション化は、パーティション空間索引ではサポートされていません。

パーティション空間索引を作成するには、LOCALキーワードを指定する必要があります。(LOCALキーワードを指定しないと、すべての表パーティションのデータに非パーティション空間索引が作成されます。)次の例ではパーティション空間索引を作成します。

CREATE INDEX counties_idx ON counties(geometry)
   INDEXTYPE IS MDSYS.SPATIAL_INDEX LOCAL;

この例では、索引パーティションの数および配置に、次のデフォルト値を使用します。

  • 索引のパーティション化は、基になる表のパーティション化に基づきます。表パーティションごとに、対応する索引パーティションが作成されます。

  • 各索引パーティションは、デフォルトの表領域に置かれます。

個々のパーティションに対してパラメータを指定する場合は、次の考慮点が適用されます。

  • 各パーティションには、各パーティションに同じ記憶特性か、またはそれぞれ異なる記憶特性を指定できます。記憶特性が異なる場合は、パラレルI/O(表領域が異なるディスク上にある場合)が使用可能になり、パフォーマンスが向上する場合があります。

  • sdo_indx_dims値には、すべてのパーティションで同じ値を指定する必要があります。

  • 各パーティションで使用されるlayer_gtypeパラメータ値(5.1.1項を参照)には異なる値を指定できます。

パーティション化のデフォルト値を上書きするには、次の一般的な形式のCREATE INDEX文を使用します。

CREATE INDEX <indexname> ON <table>(<column>) 
  INDEXTYPE IS MDSYS.SPATIAL_INDEX 
     [PARAMETERS ('<spatial-params>, <storage-params>')] LOCAL 
     [( PARTITION <index_partition> 
        PARAMETERS ('<spatial-params>, <storage-params>') 
     [, PARTITION <index_partition> 
        PARAMETERS ('<spatial-params>, <storage-params>')] 
     )] 

パーティション表で問合せを操作して、1つのパーティションのみに対する問合せを実行できます。次に例を示します。

SELECT * FROM counties PARTITION(p1)
    WHERE ...<some-spatial-predicate>;

複数の問合せを異なるパーティションで同時に操作する場合、選択したパーティションに対する問合せを行うと、問合せが高速化され、スループット全体が向上する場合もあります。

問合せでパーティション空間索引を使用する場合、空間演算子およびファンクションのセマンティック(意味または動作)は、SDO_NN(最も近くにあるもの)の場合を除いて、パーティション索引および非パーティション索引を使用する場合と同じです。SDO_NNの場合、その問合せによって影響されるパーティションごとに、要求した数のジオメトリが戻されます。(詳細は、第19章SDO_NN演算子の説明を参照してください。)

たとえば、ある地点に最も近い5つのレストランを要求し、空間索引に4つのパーティションがある場合、SDO_NNは最大20(5ラ4)のジオメトリを戻します。この場合、最も近い5つのレストランを戻すためにROWNUM疑似列(ここでは、WHERE ROWNUM <=5)を、結果を距離(マイル)でソートするためにORDER BY句を使用する必要があります。例5-1では、パーティション空間索引から最も近い5つのレストランを戻します。

例5-1 パーティション空間索引を使用したSDO_NN問合せ

SELECT * FROM
(
SELECT r.name, r.location, SDO_NN_DISTANCE(1) distance_in_miles
FROM restaurants_part_table r
WHERE SDO_NN(r.location,
      MDSYS.SDO_GEOMETRY(2001,8307,MDSYS.SDO_POINT_TYPE(-110,35,Null),Null,Null),
     'SDO_NUM_RES=5 distance=2  unit=MILE', 1) = 'TRUE'
ORDER BY distance_in_miles
)
WHERE ROWNUM<=5;

関連項目:

SDO_NN演算子を使用するその他の例については、C.3項「SDO_NNの例」を参照してください。

クロススキーマ問合せでは、表にパーティション空間索引がある場合、空間表と、空間表に作成された空間索引の索引表(MDRT_xxx)の両方について、ユーザーにSELECT権限が付与されている必要があります。詳細と例については、第19章SDO_JOIN演算子の「使用上の注意」に記載されている「SDO_JOINのクロススキーマでの使用」を参照してください。

5.1.3.1 ローカル・パーティション空間索引の作成

ローカル・パーティション空間索引を作成する場合は、PARALLELキーワードを使用するかわりに、この項の手順を使用することをお薦めします。この手順では、(表領域に空きがないなど)なんらかの理由でパーティションの索引作成に失敗した場合に、最初からやり直す必要がなくなります。次に手順を示します。

  1. ローカル空間索引を作成し、UNUSABLEキーワードを指定します。次に例を示します。

    CREATE INDEX sp_idx ON my_table (location) 
      INDEXTYPE IS mdsys.spatial_index 
      PARAMETERS ('tablespace=tb_name work_tablespace=work_tb_name') 
      LOCAL UNUSABLE;
    

    この文の実行は短時間で行われ、索引に関連付けられたメータデータが作成されます。

  2. ALTER INDEX REBUILD文を使用したスクリプトを作成しますが、PARALLELキーワードは指定しません。たとえば、パーティションが100個、プロセッサが10個ある場合は、次のようにALTER INDEX文を10個使用したスクリプトを10個作成します。

    ALTER INDEX sp_idx REBUILD PARTITION ip1;
    ALTER INDEX sp_idx REBUILD PARTITION ip2;
    . . .
    ALTER INDEX sp_idx REBUILD PARTITION ip10;
    
  3. すべてのスクリプトを同時に実行します。これにより、各プロセッサが単一パーティションの索引に対して機能する一方で、すべてのプロセッサではその一連のALTER INDEX文による動作が進められます。

ALTER INDEX文のいずれかが失敗しても、操作が正常に完了したパーティションを再作成する必要はありません。

5.1.4 索引を含むパーティションの交換

EXCHANGE PARTITION...INCLUDING INDEXES句を指定してALTER TABLE文を実行すると、空間表パーティションおよびその索引パーティションを対応する表およびその索引と交換できます。パーティションの交換については、『Oracle Database SQL言語リファレンス』のALTER TABLE文の説明を参照してください。

この機能を使用すると、次のような様々な状況でより効率的に操作を実行できます。

  • データをパーティション表に挿入し、索引作成のコストを回避する場合。

  • パーティション索引を管理および作成する場合。たとえば、データを複数表に分割できます。各表の索引を1つずつ作成して、索引作成中に必要なメモリーおよび表領域リソースを最小化できます。または、索引を複数のセッションでパラレルで作成することもできます。その後、表を(索引とともに)元のデータ表のパーティションと交換できます。

  • オフライン挿入操作を管理する場合。新しいデータを一時表に格納し、定期的に新しいパーティションと交換できます(履歴データを含むデータベース内など)。

索引を含むパーティションを空間データおよびその索引と交換するには、2つの空間索引(1つはパーティションの索引、もう1つは表の索引)が同じ次元数(sdo_indx_dims値)である必要があります。2つの索引が同じ次元数でない場合は、エラーが発生します。表データは交換されますが、索引は交換されず、変換に失敗したことが示されます。索引を使用するには、その索引を再作成する必要があります。

5.1.5 空間索引および空間データのエクスポートとインポートに関する考慮事項

エクスポート・ユーティリティを使用して空間データを含む表をエクスポートする場合、その処理の動作は、空間データが空間索引付けされているかどうかによって異なります。

  • 空間データが空間索引付けされていない場合、表データはエクスポートされます。ただし、適切な情報でターゲット・システムのUSER_SDO_GEOM_METADATAビューを更新する必要があります。

  • 空間データが空間索引付けされている場合は、表データがエクスポートされ、ターゲット・システムのUSER_SDO_GEOM_METADATAビューに適切な情報が挿入され、ターゲット・システムに空間索引が作成されます。ただし、USER_SDO_GEOM_METADATAビューへの挿入が失敗した場合(たとえば、その空間レイヤーのUSER_SDO_GEOM_METADATAエントリがすでに存在する場合)、空間索引は作成されません。

インポート・ユーティリティを使用して、空間索引付けされたデータをインポートする場合は、次の考慮点が適用されます。

  • エクスポートするデータの索引がTABLESPACE句を使用して作成された場合、その指定表領域がインポート時にデータベースに存在しないと、索引は作成されません。(これはOracleの他の索引とは異なる動作です。他の索引では、元の索引に指定された表領域がインポート時に存在しない場合、索引はユーザーのデフォルトの表領域に作成されます。)

  • 権限を持つデータベース・ユーザーがインポート操作を実行することが必要な場合にFROMUSERおよびTOUSER書式を使用するときは、インポート操作を実行する前に、次の例に示すように、CREATE TABLEおよびCREATE SEQUENCE権限をTOUSERユーザーに付与しておく必要があります(プロンプトが表示されたらSYSTEMアカウントのパスワードを入力します)。

    sqlplus system
    SQL> grant CREATE TABLE, CREATE SEQUENCE to CHRIS;
    SQL> exit;
    imp system file=spatl_data.dmp fromuser=SCOTT touser=CHRIS
    

エクスポート・ユーティリティおよびインポート・ユーティリティの詳細は、『Oracle Databaseユーティリティ』を参照してください。

5.1.6 分散トランザクションと空間索引の一貫性

分散トランザクションでは、トランザクションの複数のブランチをそれぞれ異なるセッションで実行できます。ブランチは、現行のセッションから分離し、同じトランザクション・スコープ内の別のセッションに移行する可能性があります。分散トランザクションで空間索引の一貫性を維持するには、この項の使用ガイドラインに従う必要があります。

ある分散トランザクションで、空間索引を含む空間表に対して挿入、更新または削除操作を初めて実行した後、そのトランザクションでは、同じ空間表に対する後続の挿入、更新または削除操作、および操作をコミットするための準備(コミットを準備する最初のブランチ)は、すべて最初の操作と同じセッションで実行する必要があります。これらの後続の操作を実行するブランチは、まず、操作が初めて実行されたセッションに接続する必要があります。

分散トランザクションの詳細は、『Oracle Database管理者ガイド』を参照してください。

5.1.7 ロールバック・セグメントおよびソート領域サイズ

この項は、ユーザー(データベース管理者)がOracle Databaseの自動UNDO管理機能またはPGAメモリー管理機能のいずれかを使用していないか、あるいはこの両方を使用していない場合にのみ適用されます。自動メモリー管理およびPGAメモリー管理は、デフォルトで有効になっており、これらを使用することをお薦めします。これらの機能の詳細は、次を参照してください。

  • 『Oracle Database概要』の自動UNDO管理およびUNDOセグメントに関する項

  • 『Oracle Database概要』のPGAメモリー管理に関する項

自動UNDO管理を使用していない場合、ロールバック・セグメントの大きさが十分でないと、空間索引の作成は失敗します。ロールバック・セグメントは、100×nバイト(nは索引付けされるデータの行)である必要があります。たとえば、1,000,000行ある表の場合、ロールバック・セグメントのサイズは100,000,000バイトである必要があります。

十分なロールバック・セグメントを確保する場合、または空間索引の作成時にロールバック・セグメントを拡張できないというエラーが発生した場合は、ユーザー(またはDBA)が、ロールバック・セグメントのサイズおよび構造を再確認します。適切なサイズのパブリック・ロールバック・セグメントを作成し、そのロールバック・セグメントをオンラインにします。また、大きな空間索引の操作中は、不適切で小さなロールバック・セグメントがすべてオフラインになっていることを確認してください。

PGAメモリー管理機能を使用していない場合、システム・パラメータSORT_AREA_SIZEは、索引作成に必要な時間に影響します。SORT_AREA_SIZEの値は、ソート操作で使用するメモリーの最大バイト数です。最適値はデータベースのサイズによって異なりますが、空間索引を作成する場合は1,000,000バイト以上にすることをお薦めします。SORT_AREA_SIZEの値を変更する場合は、ALTER SESSION文を使用します。次の文は、値を20,000,000バイトに変更します。

ALTER SESSION SET SORT_AREA_SIZE = 20000000;

5.2 空間データの問合せ

この項では、空間問合せと空間結合の解決のために使用する空間レイヤーの構造について説明します。

Spatialでは、1.6項で説明したとおり、空間問合せおよび空間結合を解決するために、1次フィルタ処理と2次フィルタ処理を含む2層問合せモデルを使用します。2層とは、問合せの解決のために2種類の別々の処理が実行されることを指します。両方の処理が実行されると、完全一致の結果セットが戻されます。

問合せ内の空間表に空間索引が定義されている場合、その表の名前にデータベース・リンク(dblink)名を追加することはできません。

5.2.1 空間問合せ

空間Rツリー索引では、各ジオメトリが最小境界矩形(MBR)で表現されます(1.7.1項を参照)。図5-1のような、複数のオブジェクトを含むレイヤーについて考えてみます。各オブジェクトには、ジオメトリ名が付いており(線ストリングにはgeom_1、4面のポリゴンにはgeom_2、三角形ポリゴンにはgeom_3、楕円にはgeom_4)、各オブジェクトのMBRは破線で表されています。

図5-1 ジオメトリとMBR

図5-1の説明が続きます。
図5-1「ジオメトリとMBR」の説明

一般的な空間問合せでは、問合せウィンドウ(定義された範囲またはウィンドウ)の内部に位置するすべてのオブジェクトが要求されます。動的問合せウィンドウとは、データベース内には定義されず、使用前に定義が必要な矩形領域を指します。図5-2に、図5-1と同じジオメトリに、太い点線のボックスで表されている問合せウィンドウを追加したものを示します。

図5-2 問合せウィンドウを追加したレイヤー

図5-2の説明が続きます。
図5-2「問合せウィンドウを追加したレイヤー」の説明

図5-2で、問合せウィンドウは、ジオメトリgeom_1およびgeom_2の一部と、geom_3のMBRの一部を覆っていますが、実際のgeom_3ジオメトリは覆っていません。問合せウィンドウは、geom_4ジオメトリまたはそのMBRを覆っていません。

5.2.1.1 1次フィルタ用の演算子

SDO_FILTER演算子(第19章を参照)は、Oracle Spatialの問合せ処理モデルに含まれる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です。

例5-2では、問合せウィンドウを表に挿入せずに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';   

例5-2では、(x1,y1)および(x2,y2)は、問合せウィンドウの左下および右上の角です。

例5-3では、問合せ自体にウィンドウ・パラメータを指定するのではなく、SDO_GEOMETRY型の一時的なインスタンスが、問合せウィンドウ用に構成されます。

例5-3 問合せウィンドウの一時的なインスタンスを使用した1次フィルタ

SELECT A.Feature_ID FROM TARGET A  WHERE sdo_filter(A.shape, :theWindow) = 'TRUE';   

例5-4では、問合せウィンドウが、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演算子は、問合せウィンドウをメモリー内で索引付けするため、高いパフォーマンスを実現します。

5.2.1.2 1次フィルタおよび2次フィルタ用の演算子

SDO_RELATE演算子(第19章を参照)は、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キーワード(あるいはその両方)も設定されます。詳細は、第19章SDO_RELATE演算子の説明を参照してください。

次の例では、1次フィルタおよび2次フィルタの両方の処理を実行します。この例では、図5-2に示すジオメトリのうち、問合せウィンドウ内に位置する、または部分的に重なるすべてのジオメトリが戻されます。これらの例の結果は、オブジェクトgeom_1およびgeom_2です。

例5-5では、問合せウィンドウを表に挿入せずに、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';

例5-5では、(x1,y1)および(x2,y2)は、問合せウィンドウの左下および右上の角です。

例5-6では、問合せウィンドウが、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演算子は、問合せウィンドウをメモリー内で索引付けするため、高いパフォーマンスを実現します。

5.2.1.3 WITHIN_DISTANCE演算子

SDO_WITHIN_DISTANCE演算子(第19章を参照)は、参照オブジェクトからn 距離単位内に、表内のオブジェクトの集合があるかどうかを判断するために使用されます。この演算子は、2次元のデータに空間索引が作成されている場合にのみ使用できます。参照オブジェクトは、SDO_GEOMETRYの一時的または永続的なインスタンス(一時問合せウィンドウやデータベースに格納された永続的ジオメトリなど)です。演算子の構文は次のとおりです。

SDO_WITHIN_DISTANCE(geometry1  SDO_GEOMETRY, 
                    aGeom      SDO_GEOMETRY,
                    params     VARCHAR2);

引数の意味は、次のとおりです。

  • geometry1は、表のSDO_GEOMETRY型の列です。この列は、空間索引付けされている必要があります。

  • aGeomは、SDO_GEOMETRY型のインスタンスです。

  • paramsは、演算子の動作を判断する、キーワードの値のペアを引用符で囲んだ文字列です。パラメータ・リストの詳細は、第19章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;

5.2.1.4 Nearest Neighbor演算子

SDO_NN演算子(第19章を参照)は、最も近くにあるジオメトリを識別するために使用します。この演算子は、2次元のデータに空間索引が作成されている場合にのみ使用できます。演算子の構文は次のとおりです。

SDO_NN(geometry1  SDO_GEOMETRY, 
       geometry2  SDO_GEOMETRY,
       param      VARCHAR2
       [, number  NUMBER]);

引数の意味は、次のとおりです。

  • geometry1は、表のSDO_GEOMETRY型の列です。この列は、空間索引付けされている必要があります。

  • geometry2は、SDO_GEOMETRY型のインスタンスです。

  • paramは、キーワードと値のペアを引用符で囲んだ文字列で、近くにあるジオメトリをいくつ戻すかといった、演算子の動作を決定できます。このパラメータの詳細は、第19章SDO_NN演算子を参照してください。

  • numberは、SDO_NN_DISTANCEのコールで使用される数と同じ数です。これは、SDO_NN_DISTANCE補助演算子がSDO_NNのコールに含まれている場合にのみ使用します。このパラメータの詳細は、第19章SDO_NN演算子を参照してください。

次の例では、COLA_MARKETS表のSHAPE列から、指定した点(10,7)に最も近い2つのオブジェクトを検索します。(SELECT文のオプティマイザ・ヒントの使用方法は、第19章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'; 

5.2.1.5 空間ファンクション

Spatialでは、ジオメトリ間の関係の判断、単一のジオメトリに関する情報の検索、ジオメトリの変更および結合を行うためのファンクションも提供されます。これらのすべてのファンクションでは、2次元のソース・データが考慮されます。これらのファンクションの出力値がジオメトリの場合、結果のジオメトリの次元は入力ジオメトリと同じになりますが、最初の2次元のみに操作の結果が正確に反映されます。

5.2.2 空間結合

空間結合は、条件で空間演算子を使用することを除いて、通常の結合と同じです。Spatialでは、あるレイヤーのすべてのジオメトリと別のレイヤーのすべてのジオメトリを比較する場合、空間結合に領域が必要です。これは、単一のジオメトリとレイヤーのすべてのジオメトリを比較する問合せウィンドウとは異なります。

空間結合を使用すると、「国立公園を横切る高速道路はどれか?」のような質問に対する回答を得ることができます。

次の表構造で、この例の結合の実行方法を示します。

PARKS(    GID VARCHAR2(32), SHAPE SDO_GEOMETRY)
HIGHWAYS( GID VARCHAR2(32), SHAPE SDO_GEOMETRY) 

空間結合を実行するには、SDO_JOIN演算子を使用します(第19章を参照)。次の空間結合問合せでは、高速道路と公園が交差する場所の高速道路と公園の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;

5.2.3 データおよび索引の次元と空間問合せ

空間問合せの要素には、理論上、次の次元があります。

  • 実表ジオメトリ(空間演算子形式の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次元問合せが実行されます。