如何提升Elasticsearch match查询使用or运算符时的响应性能
OR运算符match查询性能优化方案
1. 增加minimum_should_match参数折中匹配规则
这是投入最小收益最高的优化手段,无需调整索引结构,仅修改查询语句即可:不需要所有分词全部命中(and逻辑),也不需要任意分词命中(全or逻辑),而是设定匹配占比阈值,仅返回满足最低匹配度的文档,大幅减少需要参与算分、排序的文档量。
示例配置:
{ "query": { "match": { "name": { "query": "some Chinese com name", "operator": "or", "minimum_should_match": "70%" } } } }
比如查询分词后共5个词,上述配置要求至少匹配3个才会返回,既避免and逻辑无结果的问题,查询性能也接近and逻辑。
2. 优化中文分词策略
中文公司名查询如果使用了ik_max_word这类切分极细的分词模式,会把单个查询切割出大量细碎分词,or查询需要匹配的term数量成倍提升,直接导致查询耗时上涨。可以切换为ik_smart这类粗粒度分词模式,减少单查询的分词数量,降低匹配计算量,同时也能减少很多无关的匹配结果。
3. 跳过相关性算分开销
如果业务不需要按相关性排序,仅需要返回匹配的结果,可以把查询放到bool的filter上下文中执行,跳过相关性评分环节,还能命中ES的filter缓存,多次相同查询可以直接返回缓存结果,耗时会大幅下降:
{ "query": { "bool": { "filter": [ { "match": { "name": { "query": "some Chinese com name", "operator": "or", "minimum_should_match": "70%" } } } ] } } }
4. 索引结构优化
- 当前索引单主分片存储了近1亿条数据,分片容量达26.5GB,超出ES单分片最优容量(建议10-20GB)的阈值,可以把主分片数调整为3-5个,查询时多分片并行处理,能显著降低单分片的查询压力。
- 如果业务不需要根据词频算分、也不需要匹配短语,可以调整
name字段的index_options配置为docs,索引时仅存储分词是否存在的标识,不需要存储词频、位置信息,查询时加载的数据量更少,速度更快。
5. 运行时查询参数优化
- 如果业务不需要返回全量匹配结果,可以添加
terminate_after参数,设定每个分片最多扫描N条匹配结果就终止查询,避免全量扫描分片数据。 - 查询时添加
preference=local参数,优先调度到存储了对应分片的本地节点执行,避免跨节点网络传输开销。
内容的提问来源于stack exchange,提问作者zhuguowei
相关产品推荐
相关产品推荐

