我在客户机-服务器环境中使用Oracle空间的sdo_relate操作符来查询两个表,每个表都有数千个几何对象。我在where语句中应用了一个条件,只将一个对象传递给所谓的查询窗口。
使用'/*+ ordered */'提示和from子句中所需的表顺序(如Oracle空间参考中记录的),我得到了一个糟糕的性能:
SELECT /*+ ORDERED */ A.someAttr FROM Polygons A,lines B WHERE
B.id=someValue AND sdo_relate(B.geom,A.geom,
'mask=anyinteract') = 'TRUE'; --6 Min!
我认为这是反过来的,因为没有有序的提示,它需要50秒(仍然需要优化)。无论如何,似乎空间文档是错误的!http://docs.oracle.com/cd/B19306_01/appdev.102/b14255/sdo_operat.htm i78531
任何人都有这样的经历,期待你的解决方案。
关键是你的查询写错了。在所有空间操作符中,第一个列是来自您搜索的表,第二个列是您的查询窗口。所以像这样重写你的查询:
SELECT A.someAttr
FROM Polygons A,lines B
WHERE B.id=someValue
AND sdo_relate(A.geom,B.geom,'mask=anyinteract') = 'TRUE';
或简单的:
SELECT A.someAttr
FROM Polygons A,lines B
WHERE B.id=someValue
AND sdo_anyinteract(A.geom,B.geom) = 'TRUE';
这将比您指示的50秒快得多。提示是完全没有必要的。
假设你想做相反的操作(=搜索所有与给定多边形相交的线),那么你可以这样写:
SELECT A.someAttr
FROM Polygons A,lines B
WHERE A.id=someValue
AND sdo_anyinteract(B.geom,A.geom) = 'TRUE';
换句话说,您需要对SDO_ANYINTERACT的参数进行排序,以便第一个是您搜索的列的名称,而第二个是您的搜索窗口。
from子句中表的顺序并不重要,where子句中谓词的顺序也不重要:数据库优化器将生成相同的查询计划。
在子句中对表排序的唯一原因是,如果您使用/*+ order */提示让优化器按照表列出的顺序执行连接。但这在这里是不必要的(甚至可能产生负面影响)。
简单的规则是:不要使用任何提示——除非你知道你有一个问题,并且你知道使用一些特定的提示可以解决这个问题。永远不要仅仅因为你认为有必要而使用暗示。优化器足够聪明,可以生成适当的计划,只有在极少数情况下才会使用提示。