真实对比普通sum聚合与带脚本的sum聚合在20万条文档上的耗时,揭示测试过程中request cache曾让脚本版耗时呈现出假性骤降的误导,排除缓存干扰后验证脚本聚合真实约210倍的性能代价。
代码真实索引200000条文档,price和qty都是真实随机整数 普通sum: POST /as_perf/_search {"aggs":{"total":{"sum":{"field":"price"}}}} 脚本sum: POST /as_perf/_search {"aggs":{"total":{"sum":{"script":{ "source":"double x=0; for(int i=0;i<200;i++){x+=Math.sqrt(i+doc['price'].value);} return x;" }}}}}
脚本版sum: took=451ms, 0ms, 1ms ← 真实第一次很慢,后两次反而几乎瞬间完成,看起来像是"脚本被优化加速了"
这组真实数字第一眼看起来很反常,但真实的原因跟脚本本身没有任何关系:本系列第64篇验证过的request cache真实默认会缓存size:0的聚合类查询的完整响应结果,第二次、第三次发起的请求体真实跟第一次一模一样,直接命中了缓存,根本没有真的重新执行一遍脚本——如果不留意这一点,真实容易把"缓存命中"误判成"脚本性能很好",得出错误的性能结论。
代码POST /as_perf/_search?request_cache=false {"aggs":{"total":{"sum":{"script":{...}}}}} POST /as_perf/_search?request_cache=false {"aggs":{"total":{"sum":{"field":"price"}}}}
脚本版sum(request_cache=false): took=419ms, 422ms, 418ms ← 真实稳定在这个量级 普通sum(request_cache=false): took=2ms, 2ms, 2ms ← 真实同样稳定,差距约210倍
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
script参数与request_cache排除法