I have a table MY_TABLE in oracle with a Spatial index MY_IDX and about 22000 rows. The following query runs in less than ~500 ms and returns ~2600 results.
SELECT /*+ INDEX (MY_TABLE MY_IDX) */ ID,GEOM,LABEL FROM MY_TABLE
where (
(sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(-180.0,-48.0,-67.0,32.0)),
'querytype=WINDOW')='TRUE')
);
When I add an "OR" clause with another spatial filter, the query takes ~30 seconds to run, consuming vastly more CPU than it should:
SELECT /*+ INDEX (MY_TABLE MY_IDX) */ ID,GEOM,LABEL FROM MY_TABLE
where (
(sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(-180.0,-48.0,-67.0,32.0)),
'querytype=WINDOW')='TRUE')
OR
(sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(157.0,-48.0,180.0,32.0)),
'querytype=WINDOW')='TRUE')
);
The explain plans of the queries are very different - the first shows table access is "BY INDEX ROWID", where as the second is "FULL". Is there a way I can get the second query to perform in a manner similar to the first?
v$version returns:
Oracle Database 11g Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
"CORE 11.2.0.1.0 Production"
TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
On a side note, a different db running oracle enterprise edition produces a plan in which the index is used and the results merged. Can this be done with standard edition?
Refractoring the query using an inner query and a union all seemed to force oracle to use the indexes as expected:
SELECT ID,GEOM,LABEL FROM MY_TABLE
WHERE ID IN (
(SELECT ID FROM MY_TABLE WHERE sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(-180.0,-48.0,-67.0,32.0)),
'querytype=WINDOW')='TRUE')
UNION ALL
(SELECT ID FROM MY_TABLE WHERE sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(157.0,-48.0,180.0,32.0)),
'querytype=WINDOW')='TRUE')
);