Elasticsearch中Update By Query API是否适合用于更新单条文档?
Elasticsearch 两种未知索引下的单文档更新方案性能对比
针对你提到的「未知文档所属索引时更新单条文档」的场景,直接使用_update_by_query的性能开销会高于「先按ID查询索引再调用_update接口更新」的两步方案,核心差异如下:
- 扫描成本差异:
使用_update_by_query时,即便你在请求参数中添加了_id的精确匹配条件,Elasticsearch依然需要遍历你指定的所有索引/数据流的每个分片执行查询匹配,才能定位到目标文档。而先按ID跨索引查询的逻辑是Elasticsearch直接通过ID路由到对应分片获取结果,不需要全分片扫描,拿到目标索引后调用_update是定向更新对应分片的文档,整体查询成本远低于_update_by_query的全分片匹配。 - 额外机制开销:
官方文档提到的_update_by_query运行机制:When you submit an update by query request, Elasticsearch gets a snapshot of the data stream or index when it begins processing the request and updates matching documents using internal versioning.
哪怕你只更新1条文档,_update_by_query也会对请求涉及的所有索引/数据流创建一致性快照,并且执行全局的内部版本校验逻辑,这部分会产生额外的CPU和内存开销。而普通_update的版本校验仅针对目标单条文档执行,开销可以忽略。 - 冲突处理开销:
高并发更新场景下,_update_by_query的严格版本校验规则会导致更高的冲突概率,默认最多3次的冲突重试逻辑也会带来额外的性能消耗。而_update的冲突重试逻辑更轻量,也支持开发者自定义重试参数,高并发下的稳定性更好。
优化提示:如果你必须使用
_update_by_query简化请求逻辑,可以提前给所有涉及的索引绑定统一别名,并且给文档设置固定的路由键,请求时指定routing参数缩小扫描范围,能大幅降低_update_by_query的性能开销,但即便优化后,其性能依然弱于两步更新的方案。
内容的提问来源于stack exchange,提问作者Karthik Amar
相关产品推荐
相关产品推荐

