プライマリ・コンテンツに移動
Oracle® Spatial and Graph開発者ガイド
12cリリース1 (12.1)
B72470-07
目次へ移動
目次
索引へ移動
索引

前
次

18.9 SDO_NN

書式

SDO_NN(geometry1, geometry2, param [, number]);

説明

空間索引で、最も近くにあるジオメトリを識別するために使用します。

キーワードおよびパラメータ

説明

geometry1

表のジオメトリ列を指定します。列は、空間索引付けされている必要があります。データ型はSDO_GEOMETRYです。

geometry2

表のジオメトリまたはジオメトリの一時的なインスタンスを指定します。geometry1のジオメトリのうち、geometry2に最も近いジオメトリが戻されます。(geometry2は、バインド変数またはSDO_GEOMETRYコンストラクタを使用して指定します。)データ型はSDO_GEOMETRYです。

param

演算子の処理を指定します。表18-4に、使用可能なキーワードを示します。このパラメータを指定しない場合、演算子によって、すべての行がgeometry2からの距離の昇順で戻されます。データ型はVARCHAR2です。

number

SDO_NNへのコールにSDO_NN_DISTANCE補助演算子が含まれている場合、SDO_NN_DISTANCEへのコールに使用されている数と同じ数を指定します。データ型はNUMBERです。

表18-4に、paramパラメータのキーワードを示します。

表18-4 SDO_NN Paramパラメータのキーワード

キーワード 説明

距離

最も近くにあるものの検索を中止する、距離単位の数を指定します。unitキーワードも指定していない場合、デフォルトはデータに関連付けられた計測単位になります。データ型はNUMBERです。

例: 'distance=10 unit=mile'

sdo_batch_size

WHERE句を満たす結果の数を戻すためにSDO_NN式の評価を2回以上行う必要がある場合、一度に評価される行の数を指定します。Rツリー索引が使用される場合のみ使用可能です。sdo_batch_size=0 を指定した場合(またはparamパラメータを完全に省略した場合)、結果セットのサイズに適したバッチ・サイズがSpatial and Graphによって計算されます。詳細は、「使用上の注意」および「例」を参照してください。データ型はNUMBERです。

例: 'sdo_batch_size=10'

sdo_num_res

戻される結果(最も近くにあるもの)の数を指定します。sdo_batch_sizesdo_num_resも指定されていない場合、これはsdo_batch_size=0を指定しているのを同じです。詳細は、「使用上の注意」および「例」を参照してください。データ型はNUMBERです。

例: 'sdo_num_res=5'

unit

SDO_NNへのコールにdistanceキーワードまたはSDO_NN_DISTANCE補助演算子が含まれている場合、測定単位(unit=およびMDSYS.SDO_DIST_UNITSのSDO_UNIT値を引用符で囲んだ文字列)を指定します。測定単位の指定の詳細は、「測定単位のサポート」を参照してください。データ型はVARCHAR2です。デフォルトは、データに関連付けられた測定単位です。測地データの場合、デフォルトはmです。

例: 'unit=KM'

戻り値

この演算子では、問合せでgeometry2の最も近くにある、sdo_num_resに指定した数のオブジェクトをgeometry1から戻します。2つのジオメトリ・オブジェクトの近さを決定する際、各オブジェクトの表面上の2点間の最短距離が使用されます。

使用上の注意

表に空間索引が含まれない場合、または索引の作成時に指定された次元数と問合せウィンドウの次元数が一致しない場合、この演算子は無効になります。

この演算子は、常にWHERE句で使用される必要があり、この演算子を含む条件式は、SDO_NN(arg1, arg2, '<some_parameter>') = 'TRUE'の形式である必要があります。(式は'TRUE'以外のどの値とも等しくない必要があります。)

この演算子は、次の方法で使用できます。

  • レイヤーのすべてのジオメトリが候補である場合、sdo_num_resキーワードを使用して、戻されるジオメトリの数を指定します。

    sdo_num_resキーワードは、近接性のみを考慮する場合に特に役立ちます(たとえば、銀行名に関係なく、最も近い3つの銀行など)。

  • 表のジオメトリが、WHERE句で指定されたジオメトリより近くにある場合、sdo_batch_sizeキーワードを使用し、WHERE句(ROWNUM疑似列を含む)を使用して、戻されるジオメトリの数を制限します。

    sdo_batch_sizeキーワードは、同じ表の1つ以上の列を、WHERE句の最も近くにある検索列として考慮する必要がある場合に特に役立ちます(たとえば、名前にMegaBankが含まれる最も近い3つの銀行など)。

  • また、「使用上の注意」で後述するように、sdo_num_resキーワードとsdo_batch_sizeキーワードの両方を指定することもできます。

sdo_batch_sizeキーワードの例のように、RESTAURANTS表に様々なタイプのレストランが含まれ、ホテルに最も近い2軒のイタリアン・レストラン(ただし、2マイル以内)を検索する必要があると想定します。問合せは次のようになります。

SELECT r.name FROM restaurants r WHERE 
   SDO_NN(r.geometry, :my_hotel,
      'sdo_batch_size=10 distance=2 unit=mile') = 'TRUE' 
   AND r.cuisine = 'Italian' AND ROWNUM <=2; 

この例では、CUISINEがItalianである場合、結果が3つ以上戻されないように制限するには、ROWNUM <=2句を指定する必要があります。ただし、この例でsdo_batch_sizeキーワードが指定されず、またsdo_num_res=2ROWNUM <=2のかわりに指定されている場合、CUISINE値に関係なく、2マイル以内にある最も近い2軒のレストランのみが考慮され、また、考慮される2つの行のCUISINE値がItalianでない場合、この問合せでは行が戻されない可能性があります。

sdo_batch_size値は、最も近くにあるものの問合せのパフォーマンスに影響する可能性があります。一般的なガイドラインとして、WHERE句を満たすと考えられる候補行の数を指定することをお薦めします。イタリアン・レストランに対する問合せの例では、ホテルに近いレストランの約20%がイタリアン・レストランであり、2軒のレストランを検索する場合は、sdo_batch_size値を10に指定すると、最適なパフォーマンスが得られます。一方、ホテルに近いレストランの約5%のみがイタリアン・レストランであり、2軒のレストランを検索する場合は、sdo_batch_size値を40に指定することをお薦めします。

sdo_batch_size=0を指定できます。この場合、結果セットのサイズに適したバッチ・サイズがSpatial and Graphによって計算されます。ただし、計算されたバッチ・サイズが最適ではない場合もあり、この計算によって処理オーバーヘッドが発生する場合もあります。問合せに対する適切なsdo_batch_size値を判断できる場合は、sdo_batch_size=0を指定した場合より高いパフォーマンスを得ることができます。

SDO_NNへのコールでSDO_NN_DISTANCE補助演算子を使用している場合のみ、numberパラメータを指定します。この章に示すSDO_NN_DISTANCE演算子の項を参照してください。

geometry2からの距離が等しい2つ以上のオブジェクトがgeometry1から戻される場合、ファンクションをコールするたびにどのオブジェクトでも戻される可能性があります。たとえば、item_aitem_bおよびitem_cgeometry2に最も近く、かつ等しい距離にある場合、sdo_num_res=2を指定すると、これら3つのオブジェクトのうちの2つが戻されますが、3つのすべてのオブジェクトが、戻される2つのオブジェクトになる可能性があります。

SDO_NN演算子でパーティション化された空間索引(「パーティション空間索引の使用」を参照)が使用される場合、問合せ条件に基づく候補行が含まれるパーティションごとに、要求された数のジオメトリが戻されます。たとえば、ある点に最も近い5軒のレストランを要求し、空間索引が4つのパーティションを持つ場合、この演算子によって最大20 (5×4)のジオメトリが戻されます。この場合、ROWNUM疑似列(この場合はWHERE ROWNUM <=5)を使用して、5軒の最も近いレストランを戻す必要があります。

geometry1およびgeometry2が異なる座標系に基づいている場合、geometry2は、「演算子およびファンクションでの座標系が異なるジオメトリの使用」で説明するとおり、操作を実行するため一時的にgeometry1の座標系に変換されます。

SDO_NNでは空間結合をサポートしていません。

オプティマイザ・ヒントによって索引を強制的に使用しないかぎり、SDO_NN演算子が空間索引を使用しない場合があります。これは、結合を含む問合せを発行した場合に発生します。また、このような場合に、オプティマイザ・ヒントを使用しないと内部エラーが発生します。このようなエラーを防ぐには、問合せの複雑さに関係なく、常にオプティマイザ・ヒントが、SDO_NN演算子とともに空間索引を使用するように指定する必要があります。次に、COLA_MARKETS表で定義されたCOLA_SPATIAL_IDX索引を使用するように指定する問合せの例を示します。

SELECT /*+ INDEX(c cola_spatial_idx) */ 
  c.mkt_id, c.name, ... FROM cola_markets c, ...;

ただし、WHERE句内の列の条件により、関連付けられた索引を持つgeometry1の表で非空間列が1つでも指定されている場合は、その索引にNO_INDEXヒントを指定して、その索引が使用されないようにする必要があります。たとえば、COLA_NAME_IDXという名前の索引がNAME列に定義されている場合は、次のとおり前述の例にヒントを指定する必要があります。

SELECT /*+ INDEX(c cola_spatial_idx) NO_INDEX(c cola_name_idx) */ 
  c.mkt_id, c.name, ... FROM cola_markets c, ...;

(ただし、「空間データの挿入、索引付けおよび問合せの例」の例にはCOLA_NAME_IDXという名前の索引は含まれていないことに注意してください。)

SDO_NN演算子とsdo_num_resキーワードを使用して2つ以上の表を結合する場合、外部表にはLEADINGヒントを、ネステッド・ループ・ジョインを使用するためにUSE_NLヒントを、内部表(空間索引を持つ表)にはINDEXヒントを指定します。次に例を示します。

SELECT  /*+ LEADING(b) USE_NL(b a) INDEX(a cola_spatial_idx) */ a.gid
   FROM cola_qry  b,  cola_markets  a
      WHERE SDO_NN(a.shape, b.shape, 'sdo_num_res=1')='TRUE';

ただし、SDO_NN演算子、sdo_batch_sizeキーワードおよびROWNUM句を使用して2つ以上の表を結合する場合、最適なロジックの実装方法は、PL/SQLブロックを使用することになります。次に例を示します。

BEGIN
  FOR item IN ( SELECT b.shape FROM cola_qry b)
  LOOP 
    SELECT  /*+ INDEX(a cola_spatial_idx) */ a.gid INTO local_gid
    FROM cola_markets  a
    WHERE SDO_NN(a.shape, item.shape, 'sdo_batch_size=10')='TRUE'
      and a.name like 'cola%' and ROWNUM <2;
  END LOOP;
END;

オプティマイザ・ヒントの使用方法については、『Oracle Database SQLチューニング・ガイド』を参照してください。

空間演算子での3Dサポート(計算時にすべての3次元を考慮する演算子または考慮しない演算子)については、「3次元の空間オブジェクト」を参照してください。

次の例では、COLA_MARKETS表のSHAPE列から、指定した点(10,7)に最も近い2つのオブジェクトを検索します。(例では、「空間データの挿入、索引付けおよび問合せの例」および図2-1に示す定義およびデータを使用しています。)

SELECT /*+ INDEX(c 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';

    MKT_ID NAME
---------- --------------------------------
         2 cola_b
         4 cola_d

次の例では、sdo_batch_sizeキーワードを使用して、COLA_MARKETS表のSHAPE列から、指定された点(10,7)に最も近い、NAME値が「cola_d」未満の2つのオブジェクト(ROWNUM <=2)を検索します。sdo_batch_sizeの3という値は、WHERE句の条件を満たすかどうかを判断する前に評価する必要がある、最も近いジオメトリの数の最適な推測値を表します。(例では、「空間データの挿入、索引付けおよび問合せの例」の定義およびデータを使用しています。)

SELECT /*+ INDEX(c 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_batch_size=3') = 'TRUE'
   AND c.name < 'cola_d' AND ROWNUM <= 2; 

    MKT_ID NAME                                                                 
---------- --------------------------------                                     
         2 cola_b                                                               
         3 cola_c

SDO_NNのより複雑な例については、「SDO_NNの例」を参照してください。

関連項目