两个Elasticsearch查询哪个更高效?terms/match及filter解析
Elasticsearch查询效率对比及filter相关问题解答
你的两个查询
Query 1
{ "query": { "bool": { "filter": { "bool": { "must": [ { "match": { "vin": "okhifeb" } }, { "match": { "reportType": "OVERSPEEDING" } }, { "range": { "startTime": { "gte": "2023-07-01T00:00:00" } } }, { "range": { "endTime": { "lte": "2023-07-18T00:00:00" } } } ] } } } } }
Query 2
{ "query": { "bool": { "must": [ { "terms": { "vin.keyword": ["okhifeb"] } }, { "match": { "reportType": "OVERSPEEDING" } }, { "range": { "startTime": { "gte": "2023-07-01T00:00:00" } } }, { "range": { "endTime": { "lte": "2023-07-18T00:00:00" } } } ] } } }
问题解答
1. 哪个查询效率更高?
目前两者took值相近,但Query 1的长期性能会更优,核心原因是它把所有条件放在了filter子句中:
filter不需要计算文档的相关性得分,省去了这部分CPU开销;filter的结果会被Elasticsearch自动缓存到内存,后续相同条件的查询可以直接复用缓存结果,重复查询时性能提升非常明显。
而Query 2的条件都在must里,每次查询都要计算得分,且结果默认不会被缓存(query cache默认只缓存filter结果),当数据量增大或查询次数变多后,两者的性能差距会逐渐显现。
另外,Query 2用terms查询vin.keyword是精确匹配,比Query 1中match查询vin少了一步分词处理(如果vin是text类型的话),这一步Query 2更快,但整体来看Query 1的filter缓存特性带来的收益更大。
2. terms和match哪个更高效?
两者效率对比要看使用场景:
- terms查询是精确匹配,直接查找倒排索引里的对应词条,不需要分词,也不计算得分(除非放在must这类查询子句中),适合匹配keyword类型字段或text字段的keyword子字段,这种场景下terms比match高效。
- match查询会先对查询文本分词,再匹配分词后的词条,还要计算相关性得分,开销更大,适合全文检索、模糊匹配的场景,比如自然语言查询text字段,这种场景只能用match。
简单总结:精确匹配用terms(针对keyword字段)更高效;模糊检索只能用match。
3. filter的效率提升作用及适用场景
提升作用:
- 跳过打分:filter只判断文档是否符合条件,不计算相关性得分,节省CPU资源;
- 结果缓存:filter结果会被缓存到内存,重复查询相同条件时直接返回缓存,大幅提速;
- 提前过滤:在bool查询中filter会先执行,快速剔除不符合条件的文档,减少后续查询需要处理的数据量。
适用场景:
- 不需要相关性得分的查询,比如精确匹配、范围查询、布尔筛选;
- 重复执行的固定查询条件,比如固定时间范围、固定类别筛选;
- 对性能要求高,且结果不需要按相关性得分排序的查询。
你的场景里所有条件都是精确匹配或范围筛选,完全适合放在filter中。
内容的提问来源于stack exchange,提问作者makriss
相关产品推荐
相关产品推荐

