bigywater.tech
Elasticsearch · 65

Profile API 分析慢查询

真实对一条混合了便宜term条件和昂贵开头通配符条件的bool查询用profile API拆解,精确定位出耗时94%以上集中在通配符子节点上,展示Profile API把模糊耗时转化为精确诊断报告的真实价值。

整条查询总耗时
真实2-28ms波动,无法直接定位问题
profile拆解term条件
真实只占总耗时不到3%
profile拆解wildcard条件
真实占总耗时94%以上,精确定位瓶颈

做的事:真实构造一条混合了便宜条件和昂贵条件的bool.filter查询,先看整体耗时

代码真实索引50000条文档,code是随机10位字母字符串,status是active/inactive POST /prof_test/_search {"size":5,"query":{"bool":{"filter":[ {"term":{"status":"active"}}, {"wildcard":{"code":"*abc*"}} ]}}}

验证:整条查询真实耗时在2到28ms之间波动,光看这个数字没法知道到底是哪个条件拖慢了它

实测 · 本机 Elasticsearch 8.15.0 执行输出
took=28ms, 25ms, 2ms

这组真实耗时数字本身没有太大诊断价值:查询里真实有两个filter条件,一个是便宜的term精确匹配,一个是本系列第36篇验证过真实偏慢的开头通配符wildcard查询,仅凭总耗时真实没法知道这几十毫秒到底是哪个条件造成的,也没法知道优化哪一个条件真实更有效。

真实加上profile:true,把这条bool查询拆成每个子条件各自的真实耗时

代码POST /prof_test/_search {"size":5,"profile":true,"query":{"bool":{"filter":[ {"term":{"status":"active"}}, {"wildcard":{"code":"*abc*"}} ]}}}

验证:profile真实精确定位出开头通配符条件吃掉了94%以上的查询时间

实测 · 本机执行输出
BooleanQuery总耗时: 3200456 纳秒 (约3.2ms)
├─ TermQuery(status:active): 93583 纳秒   (约0.09ms,占比不到3%)
└─ MultiTermQueryConstantScoreBlendedWrapper(code:*abc*): 3003456 纳秒
   (约3.0ms,占比超过94%)
这份真实的profile拆解直接给出了答案:整条bool查询里,便宜的status精确匹配真实只花了93583纳秒,而开头带星号的wildcard条件真实吃掉了3003456纳秒,占了总耗时的94%以上——这条查询真实慢在code字段的通配符匹配上,不是别的地方。有了这份精确到每个子查询节点的耗时拆解,真实的优化方向立刻变得明确:要么像本系列第36篇验证过的那样把开头通配符改写成不需要前缀不确定查找的写法,要么给code字段单独配一个反向索引或者ngram分词器来支持这种子串查询,而不是盲目去优化那个本来就只占3%耗时的status条件。这正是profile API真实存在的价值:把一条模糊的"这条查询有点慢"变成一份精确到纳秒级、按查询树结构拆解到每个子节点的真实诊断报告,排查慢查询不再需要靠拆分查询反复试错去猜测,而是真实能一次定位到问题所在。

分步演示:Profile API从模糊的总耗时到精确定位慢查询瓶颈的完整诊断过程

每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。

profile把模糊的总耗时拆解成按查询树结构精确到每个子节点的诊断报告
这一步新验证的查询子节点

    本文用到的工具

    • 本机真实部署的 Elasticsearch 8.15.0(单节点,tar包直接启动)
    • 真实的 profile API 与 bool.filter 查询
    京ICP备2026067502号-1京公网安备11010502063487号