Elasticsearch Profile API 和 Slow Log 怎么用?如何排查慢查询?
简化版
Slow Log 用来记录超过阈值的慢查询,适合长期发现问题;Profile API 用来分析单次查询在各阶段耗时,适合定位具体慢在哪里。排查慢查询要结合 DSL、索引、分片、数据量和缓存状态。
详细版
ES 查询慢可能来自分词、评分、脚本、聚合、深分页、分片过多、字段类型不合适等。Slow Log 和 Profile API 是常用诊断工具。
- Slow Log 在索引级配置阈值,记录慢 query 和 fetch。
- Profile API 在查询中打开
profile: true,返回详细执行耗时。 - Slow Log 适合线上持续观察,Profile 适合针对性分析。
- Profile 会增加开销,不建议长期给线上高频查询开启。
- 排查时要关注查询命中、扫描、聚合、排序和脚本。
完整版教学
一、为什么慢查询不能只看接口耗时
接口慢不一定都是 ES 查询慢,ES 慢也不一定是同一个原因。一次搜索请求可能包含 query 阶段、fetch 阶段、聚合、排序、高亮、网络传输和应用反序列化。只看接口耗时会把所有问题混在一起。Slow Log 和 Profile API 的价值就是把 ES 内部耗时拆出来,让你知道慢在查询匹配、文档拉取、聚合还是某个脚本上。
GET products/_search
{
"profile": true,
"query": { "match": { "title": "phone" } }
}
记忆钩子:Slow Log 是监控摄像头,Profile API 是显微镜;一个看长期异常,一个看单次细节。
二、Slow Log 适合发现“哪些查询慢”
Slow Log 可以在索引级设置 query 和 fetch 阶段的阈值。超过阈值的请求会被记录到日志中,便于长期观察。它的好处是可以在线上持续启用较高阈值,发现真实用户流量里的慢查询。缺点是它告诉你“这类查询慢”,但不一定详细解释内部每个子步骤为什么慢。
PUT products/_settings
{
"index.search.slowlog.threshold.query.warn": "2s",
"index.search.slowlog.threshold.fetch.warn": "1s"
}
三、Profile API 适合分析“为什么慢”
Profile API 会返回查询在各 shard 上的执行细节,例如 query tree、rewrite 时间、collector 时间、各查询子句耗时。它能帮助判断是不是某个 wildcard、script、nested、聚合或排序拖慢。Profile 的代价是会增加执行开销,结果也很长,所以更适合在测试环境、复现请求或低流量时使用。不要把它当成常驻监控开关。
Profile 关注点:
哪个 shard 慢
哪个 query 子句慢
rewrite 是否异常
collector/aggregation 是否耗时
fetch 是否拖后腿
四、带数字看 query 和 fetch 的区别
假设查询阶段只花 80ms,但 fetch 阶段花 1500ms,这说明定位文档不慢,慢在取回文档、加载 _source、高亮或返回大字段。反过来,如果 query 阶段花 3 秒,fetch 只花 50ms,重点就应看 DSL、索引、过滤条件和分片扫描。把 query 和 fetch 分开,是 ES 慢查询排查的第一道分流。
| 慢的阶段 | 可能原因 |
|---|---|
| query 慢 | 查询条件、评分、脚本、分片扫描 |
| fetch 慢 | _source 大、高亮、大字段返回 |
| aggregation 慢 | 桶过多、字段类型、全局聚合 |
| sort 慢 | 排序字段无 doc_values 或命中太多 |
五、常见慢查询原因怎么归类
全文 match 慢可能是字段分词和召回太宽;term 查 text 字段可能查不到或表现异常;wildcard 前缀不固定会扫描大量词项;script query 会逐文档计算;深分页会让每个 shard 取大量候选;聚合桶太多会占用内存。排查时不要只盯“加机器”,先看 DSL 是否和 mapping、索引设计匹配。
GET products/_search
{
"query": {
"wildcard": {
"title.keyword": "*phone*"
}
}
}
六、排查流程应该怎么走
比较稳的流程是:先从接口日志拿慢请求 DSL;再看 Slow Log 判断 query/fetch 阶段;然后用 Profile API 复现;接着看 mapping、索引、分片数、数据量和返回字段;最后提出优化方案。优化可能包括改 keyword/text、增加过滤条件、调整排序字段、避免深分页、缩小 _source、改聚合口径或增加专用索引。慢查询不是一个按钮能解决的问题,而是一套证据链。
慢接口 -> 找 DSL -> Slow Log 分阶段 -> Profile 定位 -> mapping/索引验证 -> 优化并压测
七、常见误区与追问
- 误区:Profile API 可以长期在线上打开。 它有额外开销,适合诊断而不是常驻。
- 误区:Slow Log 能解释所有细节。 Slow Log 更像发现问题,Profile 才适合拆执行细节。
- 误区:ES 慢就是机器不够。 DSL、mapping、分片和返回字段设计不当更常见。
- 追问:query 慢和 fetch 慢怎么区分? 看 Slow Log 或 Profile,query 是匹配和排序,fetch 是取文档和返回。
- 追问:深分页慢怎么发现? 慢 DSL 里常见大
from,Profile 也能看到排序和候选收集成本。
八、加强记忆
Slow Log 和 Profile 可以记成“先发现,再解剖”。Slow Log 告诉你线上哪些查询超过阈值,Profile 告诉你单次查询内部哪里耗时。面试回答时按排查链路讲:拿 DSL、分 query/fetch、Profile 定位、回到 mapping 和索引优化,比单纯罗列工具更有说服力。