「実行可能」実行計画を選択するために、Oracle Spatialのを強制する方法
-
20-08-2019 - |
質問
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 のいくつかの情報のため。
所属していません StackOverflow