您的数据坐标系是什么?什么是最重要的 的 公差 强> 你有没有设置元数据?
其他一些评论:
1)不要使用与缓冲区相关的方法。只需使用远程方法。
2)对于那种查询,您不需要PL / SQL循环只需使用简单的CTAS:
create table orahancrosses as select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2 from orahan c1, orahan c2 where sdo_within_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE' and c2.mi_prinx <> c1.mi_prinx;
3)如上所述,A点和B点在2厘米范围内的耦合将返回两次:一次为(A,B),另一次为(B,A)。为了避免这种情况(并且只返回其中一个案例),然后像这样编写查询:
create table orahancrosses as select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2 from orahan c1, orahan c2 where sdo_within_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE' and c1.rowid < c2.rowid;
3)使用SDO_JOIN技术处理你提到的点数(400000+)应该运行得更好,如下所示:
create table orahancrosses as select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2 from table ( sdo_join ( 'ORAHAN','GEOLOC', 'ORAHAN','GEOLOC', 'DISTANCE=2 UNIT=CM' ) ) j, orahan c1, orahan c2 where j.rowid1 < j.rowid2 and c1.rowid = j.rowid1 and c2.rowid = j.rowid2;
这可能仍需要一段时间来处理 - 具体取决于数据库服务器的容量。如果您是Oracle Enterprise Edition的许可证,并且您的硬件具有适当的容量(核心数),则并行性可以减少所用的时间。
4)您说您使用的是Oracle 11g。什么确切的版本?版本11.2.0.4是11gR2的终端版本。不再支持任何旧版本。到现在为止你真的应该在12cR1(12.1.0.2)。在您的情况下,12.1.0.2的主要优点是矢量性能加速器功能,它可以加速许多空间功能和运营商(仅当您拥有正确的Oracle Spatial许可证时 - 它才具有免费的Oracle定位器功能)。
======================================
使用示例中的两点。让我们计算距离:
select sdo_geom.sdo_distance( sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null), sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.07336716,null),null,null), 0.005 ) distance from dual; DISTANCE ---------- .01000197 1 row selected.
注意我没有指定任何SRID。假设坐标以米为单位表示,它们之间的距离确实略大于1厘米。
正如您所注意到的,原始语法不起作用的原因是您为SDO_BUFFER()调用指定的容差。将其传递为0.5(= 50cm)以产生半径为0.02(2cm)的缓冲区。效果是产生的缓冲液有效地溶解到点本身。
例如,在公差0.5处:
select sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.5) from dual;
生产:
SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(521554.782, 4230983.08, NULL), NULL, NULL)
在公差0.005:
select sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.005) from dual;
你得到适当的缓冲区:
SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 2), SDO_ORDINATE_ARRAY(521554.782, 4230983.06, 521554.802, 4230983.08, 521554.782, 4230983.1, 521554.762, 4230983.08, 521554.782, 4230983.06))
现在非常接近的点与缓冲区匹配:
select sdo_geom.relate( sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.005), 'determine', sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.07336716,null),null,null), 0.005 ) relation from dual; RELATION ------------------------- CONTAINS 1 row selected.
现在,您的数据没有正确的显式SRID,这意味着在测量或基于距离的搜索中使用显式单位将不起作用。由于数据库不知道您的数据所处的坐标系,因此它不知道如何确定两个点的距离小于cm或m的设定数。您所能做的就是假设坐标以米为单位。
所以在上面给出的例子中,替换 'DISTANCE=2 UNIT=CM' 同 'DISTANCE=0.02'
'DISTANCE=2 UNIT=CM'
'DISTANCE=0.02'