Oracle11g 在使用inside-in语句时,如果不使用索引,则无法计算SDO_NN

Oracle11g 在使用inside-in语句时,如果不使用索引,则无法计算SDO_NN,oracle11g,oracle-spatial,Oracle11g,Oracle Spatial,如果我运行以下查询: select B3.bid as id ,B3.bshape as shape from Buildings B3 where B3.bid in ( select distinct B1.bid from Buildings B1, ( select * from Buildings B where B.bname in (select BOF.bname from Buildings_On_Fire BOF) ) B2 where s

如果我运行以下查询:

select B3.bid as id ,B3.bshape as shape 
from Buildings B3 
where B3.bid in 
(
   select distinct B1.bid from Buildings B1, 
   (
     select * from Buildings B where B.bname in (select BOF.bname from Buildings_On_Fire BOF)
   ) B2 where sdo_nn(B1.bshape, B2.bshape, 'distance=100') = 'TRUE' and B1.bname != b2.bname
)


我收到以下错误:

第1行错误:
ORA-13249:SDO_NN在没有 使用索引ORA-06512:at“MDSYS.MD”,第1723行 “MDSYS.MDERR”,第17行
ORA-06512:在“MDSYS.PRVT_IDX”第9行


但是,如果只运行以下子查询:

select distinct B1.bid from Buildings B1, 
(
   select * from Buildings B  where B.bname in (select BOF.bname from Buildings_On_Fire BOF)
) B2 where sdo_nn(B1.bshape, B2.bshape, 'distance=100') = 'TRUE' and B1.bname != b2.bname

这个执行得很好。我已经验证了空间索引,它们似乎是有效的。
我是甲骨文的新手,不知道下一步该做什么。请帮忙


如果有一个解决方案不需要更改上述查询,那将是最好的。

回答有点晚,但下面是

您得到的错误是因为优化器没有使用空间索引来求解SDO_NN运算符。与其他空间运算符(SDO_RELATE、SDO_-WIHIN_DISTANCE)相反,如果没有索引的帮助,SDO_NN无法解析

然后我再次怀疑你的疑问是不正确的。如果我理解正确的话,你要做的是找到所有距离任何着火建筑100(多少?米?)以内的建筑。为此,请使用SDO_in_DISTANCE操作符

假设您的表如下所示:

select b1.bid as id, b1.bshape as shape
from   buildings b1, 
       buildings b2, 
       buildings_on_fire bof
where  b2.bname = bof.bname
and    b1.bname <> b2.bname
and    sdo_within_distance (
         b1.bshape, b2.bshape, 
         'distance=100 unit=meter'
       ) = 'TRUE';
建筑物(投标编号,bname varchar2(30),B形状sdo_几何)

建筑物着火(投标编号:bname varchar2(30))

然后,选择将如下所示:

select b1.bid as id, b1.bshape as shape
from   buildings b1, 
       buildings b2, 
       buildings_on_fire bof
where  b2.bname = bof.bname
and    b1.bname <> b2.bname
and    sdo_within_distance (
         b1.bshape, b2.bshape, 
         'distance=100 unit=meter'
       ) = 'TRUE';
选择b1.bid作为id,b1.B形状作为形状
从b1楼开始,
b2楼,
建筑物在消防bof上
其中b2.bname=bof.bname
和b1.B名称b2.B名称
和sdo_在_距离内(
b1.B形状,b2.B形状,
'距离=100单位=米'
)=‘正确’;

这两个链接很有帮助。SDO_NN工作正常,但您需要了解它的工作原理才能正确使用它。它是通过匹配所涉及的两个表上的RTREE索引来实现的。这意味着优化器必须将该索引传递给SDO_JOIN操作符。比如:“给我5家离我最近的餐馆”。但是如果你说:“给我5家离我最近的中国餐馆”,并且有一个关于餐馆类型的索引,那么优化器可能决定使用这个类型索引而不是空间索引。如果餐馆类型非常罕见(比如一家藏式餐馆),这种情况可能会发生。为了安全起见,您需要添加一个提示以鼓励优化器使用空间索引。SDO_NN的另一个问题在上面的示例中:默认方法是(1)获取5家最近的餐厅,然后(2)仅返回所选类型的餐厅。答案可能是:没有。这是因为最近的五个城市都不是藏族。有一家藏式餐馆:但它离我们有一段距离,可能是最近的第50家。因此,SDO_NN有一种不同的语法,您不指定任何限制:搜索将继续按邻近程度处理餐馆,只保留符合所有条件的餐馆(键入,今天打开,接受信用卡,提供素食…。要将结果限制在最接近N的范围内,只需添加一个ROWNUM筛选器。