我有一个大约有5百万行的表,每行有10列代表10个维度。 我希望能够在新的输入来执行表中的搜索以使用曼哈顿距离返回最近的行。 距离是abs(Ai-Aj)+ abs(Bi-Bj)的总和...... 问题是,目前如果我进行查询,它会对整个表进行全面扫描,计算每行的距离,然后对它们进行排序以找到顶部X.
有没有办法加快流程并提高查询效率?
我在线查看了SDO_GEOMETRY的距离函数,但我找不到超过4维。
谢谢
答案 0 :(得分:2)
如果要插入点 A ,并且想要查找半径 r 附近的点(即,小于 r < / em>离开,在任何指标上),你可以做一个非常简单的查询:
select x1, x2, ..., xn
from points
where x1 between a1 - r and a1 + r
and x2 between a2 - r and a2 + r
...
and xn between an - r and an + r
...其中 A = (a1, a2, ..., an)
,找到一个绑定。如果您对x1
的所有xn
,...,points
字段都有索引,则此查询不应要求完整扫描。现在,这个结果可能包含邻域之外的点(即角落中的位),但是找到合适的子集很容易获胜:现在可以检查此子查询中的记录而不是检查表中的每一点。
您可以进一步优化此查询,因为使用曼哈顿指标,邻域将是方形的(尽管与上面成45度)并且正方形相对容易使用! (即使在10个维度上。)但是,所需的逻辑更复杂,最终可能是优化的开销。
答案 1 :(得分:0)
我建议使用function based index。您需要计算此距离,因此请使用基于函数的索引进行预计算。
您可能需要阅读following question并链接。基于函数的索引为您创建隐藏列。这个隐藏的列将保持manhanttan距离,因此排序将更容易。
感谢@ Xophmeister的评论。基于函数的索引对于任意点都无济于事。我不知道有什么sql函数可以帮到你。但是如果你愿意使用机器学习数据挖掘算法。
我建议使用k-means clustering群集您的500万行。让我们说你找到1000个集群中心。将此群集中心放在另一个表中。 根据定义群集,您的点将分配给群集中心。因此,您可以知道哪些点距离此群集中心最近 cluster(1)包含20.000个点,... cluster(987)包含10.000个点...
您的任意点将靠近一个群集。您发现您的点距群集987最近。运行您的sql,仅使用属于此群集中心的点,即10.000点。
您需要在架构中添加多个表/列才能使其生效。如果您的5.000.000行连续变化,则需要在更改时再次运行k-means群集。但如果它们是相当恒定的值,那么每周或每月一次聚类就足够了。