2

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?

4

3 回答 3

3

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')
);
于 2014-06-25T14:00:17.947 回答
1

"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?"

To complete the answer: Enterprise Edition supports bitmap indexing techniques. Often when the optimizer has a choice between using multiple indexes (or here the same spatial index for multiple predicates), it does use both of them.

It does so by getting the results from each predicate (a set of ROWIDs) and converting it in a bitmap. It is then a simple matter of combining those bitmaps (here of ORing them) and extracting the result back into a list of ROWIDs to fetch the actual results.

That does not exist in Standard Edition. The only option for the optimizer is to use one for the index (for a query that combines multiple predicates in a AND condition), or just do a full table scan with an OR (since an OR condition makes the query condition very little selective).

Replacing the OR condition with a UNION ALL is the correct approach: we now have two queries that are optimized independently, and both will use the spatial index.

于 2015-02-25T22:44:01.347 回答
0

Although Locator is available on both the Standard and Enterprise Editions of Oracle Database 11g, some Locator features require database features that are not available or are limited on the Standard Edition. Some of those Locator features and their availability are listed in http://docs.oracle.com/cd/E11882_01/appdev.112/e11830/sdo_locator.htm#SPATL1276

Your original query might be relating to "Parallel spatial index builds", which is supported with Enterprise Edition only.

于 2014-07-04T09:56:10.967 回答