真实用100万条全部匹配同一查询的文档对比track_total_hits=true/false与默认行为三种配置的耗时,量化精确计数需要遍历全部匹配文档带来的真实性能代价。
代码真实索引1000000条文档,body字段都含有"search"这个词,一次查询就能匹配全部100万条 POST /tth_big/_search {"size":10,"track_total_hits":true,"query":{"match":{"body":"search"}}} POST /tth_big/_search {"size":10,"track_total_hits":false,"query":{"match":{"body":"search"}}} POST /tth_big/_search {"size":10,"query":{"match":{"body":"search"}}} # 不传,用默认行为
track_total_hits=true(强制精确计数):
→ took=5ms, 3ms, 2ms, 2ms, 2ms
→ total={'value': 1000000, 'relation': 'eq'} ← 真实精确数到了100万
track_total_hits=false(完全跳过计数):
→ took=1ms, 1ms, 1ms, 1ms, 1ms
不传(默认行为,内部上限10000):
→ took=1ms, 1ms, 1ms, 1ms, 1ms
→ total={'value': 10000, 'relation': 'gte'} ← 真实数到1万就提前停了,不是精确值这组真实耗时对比量化了track_total_hits这个参数真实存在的代价:true强制ES把所有真正匹配的文档全部数一遍,本次实测真实要数完全部100万条才能给出精确结果,耗时真实比默认行为多了2到5倍;而默认行为和显式关闭计数这两种方式真实都只需要确认"匹配数至少达到了10000"就能提前停止,不需要真实遍历完全部匹配的文档,耗时真实稳定保持在最低水平,不会随着真实匹配文档总数的增长而变慢。
默认行为的total: {'value': 10000, 'relation': 'gte'}
← 真实的含义是"确认至少有10000条匹配,具体多少条没有继续数"
track_total_hits=false的total: 真实整个total字段都不存在,连"至少多少"都不告诉你每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
track_total_hits 参数(100万条真实索引文档)