暴力搜索#

暴力搜索,或称平面索引,是最简单的索引类型,其本质归结于穷尽的矩阵乘法。

虽然其复杂度为 \(O(N^2*D)\),但暴力搜索在以下情况是个不错的选择:

  1. 需要精确的最近邻,并且

  2. 向量数量相对较少时(几千到几百万)

对于经过大量过滤的查询,暴力搜索也是一个不错的选择,因为在这种情况下,其他算法可能难以返回预期结果。例如,当从搜索中过滤掉 90%-95% 的向量时,IVF 方法在探测次数较少的情况下可能根本无法返回任何结果,而基于图的算法由于哈希表内存有限,最终可能会跳过重要的未过滤条目。

[ C API | C++ API | Python API | Rust API ]

过滤注意事项#

由于其穷尽性,暴力搜索可能很快成为最慢但最精确的搜索形式。然而,即使索引中的向量数量非常大,暴力搜索仍然可以通过过滤来高效地搜索向量。

对于索引中 90%-99% 的向量被过滤掉的情况尤其如此,因为其他近似算法固有的分区可能根本不会在结果中包含预期的向量。在预过滤的暴力搜索情况下,计算被反转,因此距离仅在通过过滤的向量之间计算,从而显著减少了所需的计算量。

配置参数#

构建参数#

搜索参数#

调优注意事项#

暴力搜索是精确的,但这并不总是意味着它是确定性的。例如,当有许多距离相同的最近邻时,它们在不同运行中可能会有不同的排序。这在距离与 k 的截止值非常接近的点的情况下尤其明显,这可能导致最终的邻居列表与地面实况不同。这在实践中通常不是问题,并且通常可以通过增加 k 来缓解。

内存占用#

\(precision\) 是每个向量中每个元素的字节数(例如,32 位 = 4 字节)

索引占用#

原始向量:\(n\_vectors * n\_dimensions * precision\)

向量范数(对于需要它们的距离):\(n\_vectors * precision\)