用途
本技能用于诊断 Elasticsearch Query DSL 搜索缓慢的原因,并给出有实测依据的修复方案。它针对的是用户已经在运行的 bool/match/term/wildcard 查询结构,目标是找出 profile 中真正占主导的开销,重写查询以消除该开销,同时保持匹配语义不变,然后重新开启 profiling 进行测量对比。
本技能不负责将查询迁移到 ES|QL,只优化现有的 Query DSL 结构。
主要能力
- 通过 profile 定位慢查询的主要耗时来源,而非凭猜测判断。
- 根据 profile 证据对瓶颈分类:精确匹配或范围过滤被不必要评分、前导通配符导致无法使用倒排索引、文本字段上的 match 评分开销、聚合耗时等。
- 在重写前检查字段映射,确认字段类型(keyword、text、wildcard 等),只提出与已确认类型相符的重写方案。
- 将非评分子句从 must 移入 filter,保留影响 _score 的子句在 must 中。
- 消除前导通配符,根据映射和用户意图选择 match/match_phrase、prefix、ngram 等替代方案。
- 可选地使用 _validate/query?explain=true 在 profiling 前验证重写语义。
- 重新 profile 重写后的查询,与基线对比 took 和主要 collector 的 time_in_nanos。
使用方式
本技能通过 elastic CLI 执行 Elasticsearch 操作。如果未安装 elastic CLI,应告知用户其用途,不要猜测凭据、不要直接调用 HTTP API 或尝试其他变通方法。
文档中以 HTTP 简写形式引用操作(如 GET /、GET /_cat/indices、GET /{index}/_mapping、GET /{index}/_settings/index.mode、POST /_query),并在末尾的操作表中映射到对应的 elastic CLI 命令,始终使用 CLI 而非直接调用 HTTP API。
典型流程:
- 确认连通性并定位目标索引。调用 GET /,失败则停止。用户给出索引模式时,用 GET /_cat/indices 缩小候选范围。
- 对慢查询开启 profile 定位主要开销。调用 POST /{index}/_search 并设置 "profile": true,保持用户查询不变。读取 took,检查 profile.shards[].searches[].query,按 time_in_nanos 排序子 collector,找出最大贡献者。
- 重写前检查字段映射。调用 GET /{index}/_mapping,确认每个将被移动或重写的子句所引用字段的类型。
- 重写查询以消除 profile 中的瓶颈:将非评分子句从 must 移入 filter;消除前导通配符;可选地先验证重写。
- 重新 profile 重写后的查询并对比。再次调用 POST /{index}/_search 并设置 "profile": true,对比 took 和主要 collector。只有当主导 collector 发生变化或 time_in_nanos 明显下降时才报告成功。
- 按顺序报告发现:根因(引用 profile)、重写方案、映射说明、实测改进、语义注意事项(仅在重写可能改变匹配文档时说明)。
适用场景
- 搜索变慢,需要定位原因。
- profile 输出显示某个子句开销过高。
- 精确匹配(term/terms/range)被放在 must 中与全文匹配一起参与评分。
- 通配符查询(尤其是前导通配符)拖慢延迟。
- 需要在不改变匹配结果的前提下优化查询性能。
限制
- 仅针对通过 POST /{index}/_search 执行的 Query DSL 搜索,不迁移到 ES|QL。
- 依赖 elastic CLI,未安装时不应猜测凭据或直接调用 HTTP API。
- 聚合耗时属于查询调优之外的范围,除非用户明确询问聚合。
- 当 profile 已指出具体子句时,不应将“增加分区”或“扩容硬件”作为首选修复方案;基础设施变更需要证据表明查询已经最优。
- 重写可能改变匹配文档时,必须明确说明语义权衡。
- 文档中未提供具体收费、价格、平台支持范围等信息。