我在2个不同的Oracle服务器上拥有相同的数据库,一个是11.2.0.1.0,另一个是11.2.0.4.0。 我在两个数据库中都有相同的2个几何表,并在两个服务器上运行以下查询。在11.2.0.1.0版本的Oracle上运行时,查询运行几分钟后我得到结果,同样的查询在11.2.0.4.0运行时运行约3秒并且不返回任何结果。
BLPUs表包含3600万个点,PD_B2表包含多边形。我试图找到落在多边形中的所有点。 其他空间查询确实返回行但是需要数小时和数小时,而Oracle Spatial文档中建议的表连接需要15分钟才能返回所有点。
SELECT /*+ ordered */ a.uprn
FROM TABLE(SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')) c, blpus a, PD_B2 b
WHERE c.rowid1 = a.rowid
AND c.rowid2 = b.rowid;
以下空间查询在11.2.0.4服务器上运行时返回SDO_ROWIDSET()
select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')
from dual;
select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC')
from dual;
在11.2.0.1服务器上,它们返回结果。
我发现一个小得多的点表可以在11.2.0.4上工作,因此在使用SDO_JOIN时11.2.0.4似乎有一个大小限制,因为11.2.0.1似乎可以处理大表。
有没有人知道为什么会这样,或者在使用SDO_JOIN时是否存在对表格大小的实际限制?
答案 0 :(得分:0)
这很奇怪。我认为没有理由说SDO_JOIN在11.2.0.4中不会以相同的方式工作。至少我以前没见过那种行为。对我来说这看起来像个错误,我建议您向Oracle Support提交服务请求,以便我们查看。您可能需要提供表的转储 - 或者至少是足以证明问题的子集。
那说有几件事需要检查:你是否在同一个数据库中应用了11.2.0.4补丁?即在表格结构或内容,资助等方面没有任何改变?
当你说查询没有返回任何行时,它会立即这样做吗?或者它在完成之前是否执行了一些处理而没有返回任何内容?
PD_B2表有多大?
当你这样做时会发生什么:
select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC','mask=ANYINTERACT')
from dual;
这是否也没有返回?
如果你这样做会怎样?
select SDO_JOIN('BLPUS', 'GEOLOC', 'PD_B2', 'GEOLOC')
from dual;
两者都应该返回如下内容:
SDO_ROWIDSET(SDO_ROWIDPAIR('AAAW3LAAGAAAADmAAu', 'AAAW3TAAGAAAAg7AAC'), SDO_ROWIDPAIR('AAAW3LAAGAAAADmABE', 'AAAW3TAAGAAAAgrAAA'),...)
如果在sqlplus中运行查询,您将看到此内容。 [如果您使用GUI(如TOAD或SQLDeveloper),那么您可能看不到。所有这些GUI在处理对象或数组时都存在问题。]
但是你的11.2.0.4测试很快完成的事实可能意味着你得到一个空结果,可能是这样的:
SDO_ROWIDSET()
这证实了某些东西不起作用。
现在,从你说的PD_B2只包含一行?如果是这样,那么没有任何理由通过SDO_JOIN。简单的空间查询更容易编写。 SDO_JOIN仅在连接的两个表包含多行时才有意义。然后,如果其中一个表非常小(如您的情况下的PD_B2表),那么无论如何它都会回到简单查询。
一个简单的查询将如下所示:
SELECT a.uprn
FROM blpus a, PD_B2 b
WHERE sdo_anyinteract (a.geoloc, b.geoloc) = 'TRUE';
这是否会返回您在11.2.0.4中的期望?
您可能还想检查查询的成本和使用的查询计划。在sqlplus中,执行以下操作:
set timing on
set autotrace traceonly
然后运行上面的查询。结果是sqlplus不会显示任何结果 - 但它仍然会获取并格式化输出:它不会打印它们。最后,您将获得所使用的查询计划的打印输出以及一些执行统计信息和已用时间。请将这些结果添加到您的问题中。
从应用程序中运行查询应具有类似的配置文件:类似的响应时间和数据库端成本 - 假设您确实获取了所有130万行。
顺便说一句,你对这些结果怎么办?你把它们作为报告出示了吗?你把它们保存在一张桌子里供以后分析吗?当然你不想在地图上全部显示它们吗?澄清:SDO_JOIN仅用于匹配多个到多个几何。要将一个与多个匹配,您需要的是简单的SDO_ANYINTERACT()。事实上,当其中一个集合比另一个集合小得多时,SDO_JOIN将自动回退到简单的SDO_ANYINTERACT。我无法看到SDO_JOIN在您的情况下如何更快(即搜索匹配一个对象的所有对象时),因为它将执行与SDO_ANYINTERACT相同的操作,并且需要额外连接到两个表。
回到原始问题 - 在11.2.0.1和11.2.0.4之间的SDO_JOIN中的行为差异,IMO绝对是您需要向Oracle支持报告的错误。