Oracle是否可以强制将sdo_filter的空间索引与or子句结合使用?

时间:2014-06-25 12:12:47

标签: sql oracle oracle-spatial

我在oracle中有一个表MY_TABLE,其空间索引为MY_IDX,大约有22000行。以下查询运行时间小于~500毫秒,并返回~2600个结果。

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”子句时,查询需要大约30秒才能运行,消耗的CPU比它应该多得多:

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')
);

查询的解释计划非常不同 - 第一个显示表访问是“BY INDEX ROWID”,其中第二个是“FULL”。有没有办法让第二个查询以类似于第一个查询的方式执行?

v $ version返回:

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

另外,运行oracle企业版的不同数据库会生成一个计划,在该计划中使用索引并合并结果。这可以用标准版来完成吗?

3 个答案:

答案 0 :(得分:3)

使用内部查询和联合来反射查询似乎迫使oracle按预期使用索引:

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')
);

答案 1 :(得分:1)

在旁注中,运行oracle企业版的不同数据库会生成一个使用索引并合并结果的计划。这可以通过标准版完成吗?

要完成答案:Enterprise Edition支持位图索引技术。通常,当优化器可以选择使用多个索引(或者多个谓词使用相同的空间索引)时,它会同时使用它们。

通过从每个谓词(一组ROWID)获取结果并将其转换为位图来实现。然后组合这些位图(这里是ORing它们)并将结果提取回ROWID列表以获取实际结果是一件简单的事情。

标准版中不存在。优化器的唯一选择是使用一个用于索引(对于在AND条件中组合多个谓词的查询),或者仅使用OR执行全表扫描(因为OR条件使查询条件非常少选择性)

用UNION ALL替换OR条件是正确的方法:我们现在有两个独立优化的查询,并且都将使用空间索引。

答案 2 :(得分:0)

虽然Locator在Oracle Database 11g的标准版和企业版上均可用,但某些Locator功能需要不可用或在Standard Edition上受限的数据库功能。其中一些定位器功能及其可用性列在http://docs.oracle.com/cd/E11882_01/appdev.112/e11830/sdo_locator.htm#SPATL1276

您的原始查询可能与"并行空间索引构建"有关,仅受企业版支持。