質問

Oracle 10gのでは、

A(空間)クエリは、唯一のパラメータの値に応じて、異なる実行計画を取得します。そして、悲しいことにOracleはエラーを与え、全くプランのいずれかを実行することはできません。 (= <へ)(284から282以下)の値又はオペレータを変更すると、結果が得られます。なぜ計画は異なっていますか?なぜOracleは、実行不可能な計画を選択しますか?実行可能な実行計画を選択するには、Oracleを強制的に何をしますか?

クエリます:

  select nn.poi_id as id 
  from 
    poi p,
    (select pl.poi_id 
    from 
      poi_loc pl, 
      poi_loc pl2 
    where
     pl2.poi_id = 769
     and 
     pl.poi_id<>769
     and 
     sdo_nn(pl.wgs84, pl2.wgs84)='TRUE' 
  ) nn
  where
    cat_id = 282
    and
    p.id = nn.poi_id
       and 
     rownum<7;

エラーを与える:

ORA-13249: SDO_NN cannot be evaluated without using index
ORA-06512: at "MDSYS.MD", line 1723
ORA-06512: at "MDSYS.MDERR", line 17
ORA-06512: at "MDSYS.PRVT_IDX", line 22

は実行されませんプランます:

| Id  | Operation                       | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                         |     1 |   315 |     6   (0)| 00:00:01 |
|*  1 |  COUNT STOPKEY                  |                         |       |       |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID   | POI_LOC                 |     1 |   153 |     2   (0)| 00:00:01 |
|   3 |    NESTED LOOPS                 |                         |     1 |   315 |     6   (0)| 00:00:01 |
|   4 |     NESTED LOOPS                |                         |     1 |   162 |     4   (0)| 00:00:01 |
|*  5 |      TABLE ACCESS BY INDEX ROWID| POI                     |     1 |     9 |     2   (0)| 00:00:01 |
|*  6 |       INDEX RANGE SCAN          | POI_CAT_ID_IDX          |     1 |       |     1   (0)| 00:00:01 |
|   7 |      TABLE ACCESS BY INDEX ROWID| POI_LOC                 |     1 |   153 |     2   (0)| 00:00:01 |
|*  8 |       INDEX RANGE SCAN          | POI_LOC_POI_ID_IDX      |     1 |       |     1   (0)| 00:00:01 |
|*  9 |     INDEX RANGE SCAN            | POI_LOC_POI_ID_IDX      |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------

   1 - filter(ROWNUM<7)
   2 - filter("MDSYS"."SDO_NN"("PL"."WGS84","PL2"."WGS84")='TRUE')
   5 - filter("P"."ID"<>769)
   6 - access("CAT_ID"=282)
   8 - access("P"."ID"="PL"."POI_ID")
       filter("PL"."POI_ID"<>769)
   9 - access("PL2"."POI_ID"=769)

実行し、結果を与える計画

| Id  | Operation                      | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                         |     6 |  1890 |   106   (1)| 00:00:02 |
|*  1 |  COUNT STOPKEY                 |                         |       |       |            |          |
|*  2 |   HASH JOIN                    |                         |     6 |  1890 |   106   (1)| 00:00:02 |
|*  3 |    TABLE ACCESS BY INDEX ROWID | POI                     |   573 |  5157 |    41   (0)| 00:00:01 |
|*  4 |     INDEX RANGE SCAN           | POI_CAT_ID_IDX          |   573 |       |     2   (0)| 00:00:01 |
|   5 |    NESTED LOOPS                |                         |   301 | 92106 |    65   (2)| 00:00:01 |
|   6 |     TABLE ACCESS BY INDEX ROWID| POI_LOC                 |     1 |   153 |     2   (0)| 00:00:01 |
|*  7 |      INDEX RANGE SCAN          | POI_LOC_POI_ID_IDX      |     1 |       |     1   (0)| 00:00:01 |
|*  8 |     TABLE ACCESS BY INDEX ROWID| POI_LOC                 |   302 | 46206 |    65   (2)| 00:00:01 |
|*  9 |      DOMAIN INDEX              | POI_LOC_SP_IDX          |       |       |            |          |
Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(ROWNUM<7)
   2 - access("P"."ID"="PL"."POI_ID")
   3 - filter("P"."ID"<>769)
   4 - access("CAT_ID"=284)
   7 - access("PL2"."POI_ID"=769)
   8 - filter("PL"."POI_ID"<>769)
   9 - access("MDSYS"."SDO_NN"("PL"."WGS84","PL2"."WGS84")='TRUE')
役に立ちましたか?

解決

あなただけのヒントに適切な方法を記述する必要があります:

select nn.poi_id as id 
  from 
    poi p,
    (select /*+ index (pl POI_LOC_SP_IDX) */ pl.poi_id 
    from 
      poi_loc pl, 
      poi_loc pl2 
    where
     pl2.poi_id = 769
     and 
     pl.poi_id<>769
     and 
     sdo_nn(pl.wgs84, pl2.wgs84)='TRUE' 
  ) nn
  where
    cat_id = 282
    and
    p.id = nn.poi_id
    and rownum<7;

エラーの理由は、オプティマイザは、それが他の(非空間)インデックスさ述語は、より選択的であると考えるので、空間インデックスを使用しないことを選択することです。明確にする:あなたは仕事に空間問合せのための空間インデックスを持っている必要がありますが、オプティマイザは、それを使用しないことも選択できます。これは、SDO_RELATEとSDO_ANYINTERACT事業者にとって、なくSDO_NNのために正常に動作します。

他のヒント

いずれにせよ、あなたはWGS84のインデックスを追加する必要があります。

あなたはすべてこれが何を意味するのか見当もつかない場合は、DBAに尋ねます。

のhttpを参照してください:// download-west.oracle.com/docs/cd/B19306_01/appdev.102/b14255/sdo_index_query.htm#i1000846 のいくつかの情報のため。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top