在 Oracle 中进行空间连接的正确方法是什么?

What's the proper way to do a spatial join in Oracle?

Oracle 有一个名为 SDO_JOIN 的 table 函数,用于根据空间关系连接 table。查找房屋所在社区的示例查询如下所示:

select 
    house.address,
    neighbourhood.name
from table(sdo_join('HOUSE', 'GEOMETRY', 'NEIGHBOURHOOD', 'GEOMETRY', 'mask=INSIDE')) a 
inner join house
    on a.rowid1 = house.rowid
inner join neighbourhood
    on a.rowid2 = neighbourhood.rowid;

但是我通过在 on 子句中使用空间关系进行常规连接得到了相同的结果:

select 
    house.address,
    neighbourhood.name
from house
inner join neighbourhood
    on sdo_inside(house.geometry, neighbourhood.geometry) = 'TRUE';

我更喜欢第二种方法,因为我认为它更容易理解究竟发生了什么,但我找不到任何关于这是否是进行空间连接的正确方法的 Oracle 文档。

这两种方法有什么区别吗?如果有,是什么?如果没有,哪种款式比较常见?

区别在于性能。

第一种方法 (SDO_JOIN) 通过匹配每个 table 上的 RTREE 索引来隔离候选者。

第二种方法将在 HOUSE table 中搜索 NEIGHBORHOOD table 的每个几何形状。

很大程度上取决于您的 table 有多大,尤其是 NEIGHBORHOOD table 有多大 - 或者更准确地说,NEIGHBORHOOD table 有多少行您的查询实际使用。如果 NEIGHBORHOOD table 很小(少于 1000 行),那么第二种方法很好(HOUSE table 的大小无关紧要)。

另一方面,如果您需要匹配数百万个房屋和数百万个街区,那么 SDO_JOIN 方法会更有效。

请注意,SDO_INSIDE 方法也很有效:只需确保启用 SPATIAL_VECTOR_ACCELERATION(仅当您使用 Oracle 12.1 或 12.2 时具有 Oracle Spatial and Graph 的适当许可)并使用并行性。