Oracle 10g의 (공간) 쿼리는 매개 변수 값에 따라 다른 실행 계획을 얻습니다. 그리고 슬프게도 오라클은 계획 중 하나를 전혀 실행할 수 없으므로 오류가 발생합니다. 값을 변경 (282 미만에서 284 이하)하거나 연산자 (= <에서)로 변경하면 결과가 나타납니다. 계획이 다른 이유는 무엇입니까? 왜 oracle은 실행 불가능한 계획을 선택합니까? 오라클이 실행 가능한 실행 계획을 선택하게하려면 어떻게해야합니까?Oracle Spatial에서 "실행 가능한"실행 계획을 선택하도록하는 방법
쿼리 :
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 | | 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')
에게 제공
| 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)
계획
색인이 이미 있습니다. 오라클이 매번 그것을 사용하도록 어떻게 할 수 있습니까? – Riivo
인덱스가 이미있는 경우 계획이 오래되었을 수 있습니다. pl/sql 인 경우 다시 컴파일하십시오. 그렇지 않으면 dbms_stats 팩으로 통계를 업데이트하십시오. 이러한 모든 작업을 수행 한 후에도 여전히 작동하지 않으면 옵티 마이저 힌트를 사용하십시오. ID/BLUE blar blar blar –
계획이 오래되었다고 생각하지 않습니다. SELECT/* + INDEX (YOU_INDEX_NAME) */nn.poi_id as id . 그것의 평범한 SQL. 값에 따라 때때로 POI_LOC_SP_IDX를 사용하는 계획을 선택하고 쿼리가 올바르게 작동합니다. 이 힌트는이 경우에도 도움이되지 않습니다. – Riivo