搜索性能调优
请采取以下步骤来提升搜索性能。
减少段数量
为了提升搜索性能,您必须控制好段的数量。Lucene 的 IndexSearcher 会搜索分片中的所有段,以找到 ‘size’ 个最佳结果。
每个分片拥有一个段可以提供最佳的搜索延迟性能。您可以配置索引以拥有多个分片,从而避免非常大的分片并实现更高的并行度。
您可以通过选择更大的刷新间隔来控制段的数量,或者在索引期间通过禁用刷新间隔来要求 OpenSearch 减慢段的创建速度。
预热索引
原生库索引在索引期间构建,但在首次搜索期间加载到内存中。在 Lucene 中,每个段都按顺序搜索(因此,对于 k-NN,每个段最多返回查询点的 k 个最近邻居)。得分最高的 size
个结果,按分数排序,从分片内的所有段级别结果中返回(分数越高表示结果越好)。
原生库索引加载后(原生库索引在 OpenSearch JVM 之外加载),OpenSearch 会将其缓存到内存中。初始查询成本较高,需要几秒钟才能完成,而后续查询速度更快,只需几毫秒即可完成(假设 k-NN 断路器未触发)。
从 3.1 版本开始,您可以使用 内存优化搜索模式,该模式使引擎在搜索期间仅加载必要的字节,而不是在 JVM 外部加载整个索引。启用此模式后,预热 API 会将最少量必要信息加载到内存中,包括打开对底层索引的读取流。因此,即使启用了内存优化搜索,预热 API 也有助于确保预热后的搜索运行更快。
为了避免首次查询期间的此延迟惩罚,您可以在要搜索的索引上使用预热 API 操作
GET /_plugins/_knn/warmup/index1,index2,index3?pretty
{
"_shards" : {
"total" : 6,
"successful" : 6,
"failed" : 0
}
}
预热 API 操作将指定索引的所有分片(主分片和副本分片)的所有原生库索引加载到缓存中,因此在初始搜索期间加载原生库索引不会有性能损失。
此 API 操作仅将活动索引的段加载到缓存中。如果在 API 运行后合并或刷新操作完成,或者您添加了新文档,则需要重新运行 API 以将这些原生库索引加载到内存中。
避免读取存储字段
如果您的用例只涉及读取最近邻居的 ID 和分数,您可以禁用存储字段的读取,这样可以节省否则用于从存储字段检索向量的时间。要完全禁用存储字段,请将 _source
设置为 false
GET /my-index/_search
{
"_source": false,
"query": {
"knn": {
"vector_field": {
"vector": [ 0.1, 0.2, 0.3],
"k": 10
}
}
}
}
此查询仅返回文档 ID 和分数,当您不需要实际文档内容时,这是最快的选项。有关更多信息,请参阅禁用 _source
。
从搜索结果中排除向量
如果您需要文档内容但想优化性能,可以只排除向量字段不显示在搜索结果中。这种方法可以减少网络传输,同时仍然可以访问其他文档字段。要从搜索结果中排除向量,请在 _source.excludes
中提供向量字段名称。
GET /my-index/_search
{
"_source": {
"excludes": [
"vector_field"
]
},
"query": {
"knn": {
"vector_field": {
"vector": [ 0.1, 0.2, 0.3],
"k": 10
}
}
}
}
有关更多信息,请参阅检索特定字段。