如果没有kibana管理台页面工具还可以用postman_search不带条件查询curl --location --request GET http://ip:9200/xxx-gift_pack_record202409/_search \ --header Authorization: Basic ZWxhc3RpYzpIaWhvbm9yQG1hcmtldDFuZw_search带条件查询curl --location --request GET http://ip:9200/xxx-t_prize_grant_record202409/_search \ --header Authorization: Basic ZWxhc3RpYzpIaWhvbm9yQG1hcmtldDFuZw \ --header Content-Type: application/json \ --data-raw { from: 0, size: 15, query: { bool: { filter: [ {term: {prize_type: {value: 8, boost: 1.0}}}, {range: {reward_time: {from: 2024-09-01 00:00:00, to: 2026-09-30 23:59:59, include_lower: true, include_upper: true, boost: 1.0}}}, {term: {es_delete_flag: {value: false, boost: 1.0}}} ], adjust_pure_negative: true, boost: 1.0 } }, sort: [ {reward_time: {order: desc}}, {grant_id: {order: desc}} ], track_total_hits: 2147483647 }_count查询curl --location --request GET http://ip:9200/xxx-t_prize_grant_record202409/_count \ --header Authorization: Basic ZWxhc3RpYzpIaWhvbm9yQG1hcmtldDFuZw \ --header Content-Type: application/json \ --data-raw { query: { bool: { filter: [ {term: {prize_type: {value: 8, boost: 1.0}}}, {range: {reward_time: {from: 2024-09-01 00:00:00, to: 2026-09-30 23:59:59, include_lower: true, include_upper: true, boost: 1.0}}}, {term: {es_delete_flag: {value: false, boost: 1.0}}} ], adjust_pure_negative: true, boost: 1.0 } } }profile分析curl --location --request GET http://ip:9200/xxx-t_prize_grant_record202409/_search \ --header Authorization: Basic ZWxhc3RpYzpIaWhvbm9yQG1hcmtldDFuZw \ --header Content-Type: application/json \ --data-raw { profile: true, from: 0, size: 15, query: { bool: { filter: [ {term: {prize_type: {value: 8, boost: 1.0}}}, {range: {reward_time: {from: 2024-09-01 00:00:00, to: 2026-09-30 23:59:59, include_lower: true, include_upper: true, boost: 1.0}}}, {term: {es_delete_flag: {value: false, boost: 1.0}}} ], adjust_pure_negative: true, boost: 1.0 } }, sort: [ {reward_time: {order: desc}}, {grant_id: {order: desc}} ], track_total_hits: 2147483647 }在查询里加上 profile: trueexplain分析curl --location --request GET http://ip:9200/xxx-t_prize_grant_record202409/_search \ --header Authorization: Basic ZWxhc3RpYzpIaWhvbm9yQG1hcmtldDFuZw \ --header Content-Type: application/json \ --data-raw { explain: true, from: 0, size: 15, query: { bool: { filter: [ { term: { prize_type: { value: 8, boost: 1.0 } } }, { range: { reward_time: { from: 2024-09-01 00:00:00, to: 2026-09-30 23:59:59, include_lower: true, include_upper: true, boost: 1.0 } } }, { term: { es_delete_flag: { value: false, boost: 1.0 } } } ], adjust_pure_negative: true, boost: 1.0 } }, sort: [ { reward_time: { order: desc } }, { grant_id: { order: desc } } ], track_total_hits: 2147483647 }在查询里加上 explain: true Elasticsearch 的 Explain 和 Profile 功能详解Explain解释查询作用解释为什么某个文档匹配或不匹配查询显示评分计算过程。使用场景调试相关性评分问题理解查询匹配逻辑优化查询性能使用方法# 方式1使用 _explain 端点 GET /index_name/_explain/doc_id { query: { match: { field: search term } } } # 方式2在 _search 中添加 explain 参数 GET /index_name/_search { explain: true, query: { match: { field: search term } } }返回信息包含value匹配得分description评分描述details详细的评分计算过程matched是否匹配⚡Profile性能分析作用详细分析查询执行过程识别性能瓶颈。使用场景优化复杂查询性能识别慢查询原因分析聚合操作性能使用方法GET /index_name/_search { profile: true, query: { match: { field: search term } } }返回信息包含查询阶段Query Phasequery查询执行详情rewrite_time查询重写时间collectors结果收集器信息获取阶段Fetch Phasefetch文档获取详情load_source源数据加载时间聚合阶段Aggregation Phase聚合操作执行详情两者区别特性ExplainProfile目的解释评分机制分析性能瓶颈输出评分计算详情时间消耗详情粒度单个文档整个查询使用场景相关性调试性能优化实际应用示例Explain 示例结果_explanation: { value: 0.0, description: sum of:, details: [ { value: 0.0, description: match on required clause, product of:, details: [ { value: 0.0, description: # clause, details: [] }, { value: 1.0, description: prize_type:[8 TO 8], details: [] } ] }, { value: 0.0, description: match on required clause, product of:, details: [ { value: 0.0, description: # clause, details: [] }, { value: 1.0, description: DocValuesFieldExistsQuery [fieldreward_time], details: [] } ] }, { value: 0.0, description: match on required clause, product of:, details: [ { value: 0.0, description: # clause, details: [] }, { value: 1.0, description: es_delete_flag:F, details: [] } ] } ] }整体含义value: 0.0这个文档的最终相关性评分是0分description: sum of:总评分是由多个子评分相加得到的三个必须子句分析您的查询包含三个必须匹配的条件每个条件都产生了0分1.第一个条件prize_type 匹配{ value: 0.0, description: match on required clause, product of:, details: [ {value: 0.0, description: # clause, details: []}, {value: 1.0, description: prize_type:[8 TO 8], details: []} ] }✅prize_type:[8 TO 8]值为1.0表示prize_type8匹配成功❓# clause值为0.0这是Elasticsearch内部计算的一个因子2.第二个条件reward_time 字段存在性检查{ value: 0.0, description: match on required clause, product of:, details: [ {value: 0.0, description: # clause, details: []}, {value: 1.0, description: DocValuesFieldExistsQuery [fieldreward_time], details: []} ] }✅DocValuesFieldExistsQuery [fieldreward_time]值为1.0表示reward_time字段存在❓# clause值为0.03.第三个条件es_delete_flag 匹配{ value: 0.0, description: match on required clause, product of:, details: [ {value: 0.0, description: # clause, details: []}, {value: 1.0, description: es_delete_flag:F, details: []} ] }✅es_delete_flag:F值为1.0表示es_delete_flagF匹配成功❓# clause值为0.0关键结论所有三个条件都匹配成功prize_type8✅reward_time字段存在 ✅es_delete_flagF✅但最终评分是0这是因为您使用的是filter上下文不是query上下文在过滤上下文中Elasticsearch不计算相关性评分所有匹配文档的评分都是0这是正常且预期的行为# clause值为0的解释这是Elasticsearch内部用于计算的一个因子在filter上下文中这个值被设置为0因为不需要计算相关性为什么这样设计性能优化filter上下文跳过评分计算性能更好缓存友好filter结果可以被缓存提高查询速度布尔逻辑只关心是否匹配不关心匹配程度✅您的查询是正常的您的查询完全正确所有条件都匹配成功。评分为0是filter上下文的正常行为表示✅ 文档匹配所有过滤条件✅ 应该被包含在结果集中✅ 只是没有计算相关性评分而已不需要担心这个0分这是Elasticsearch filter查询的标准行为Profile 示例结果profile: { shards: [ { id: [REHyAdbwSWS8DMd8dOCkGQ][marketing_test_drcn-t_prize_grant_record202409][0], searches: [ { query: [ { type: BooleanQuery, description: #prize_type:[8 TO 8] #ConstantScore(DocValuesFieldExistsQuery [fieldreward_time]) #es_delete_flag:F, time_in_nanos: 4064629, breakdown: { set_min_competitive_score_count: 0, match_count: 0, shallow_advance_count: 0, set_min_competitive_score: 0, next_doc: 3636537, match: 0, next_doc_count: 24754, score_count: 0, compute_max_score_count: 0, compute_max_score: 0, advance: 22021, advance_count: 2, score: 0, build_scorer_count: 7, create_weight: 31850, shallow_advance: 0, create_weight_count: 1, build_scorer: 374221 }, children: [ { type: IndexOrDocValuesQuery, description: prize_type:[8 TO 8], time_in_nanos: 1248668, breakdown: { set_min_competitive_score_count: 0, match_count: 0, shallow_advance_count: 0, set_min_competitive_score: 0, next_doc: 973861, match: 0, next_doc_count: 24754, score_count: 0, compute_max_score_count: 0, compute_max_score: 0, advance: 511, advance_count: 4, score: 0, build_scorer_count: 9, create_weight: 461, shallow_advance: 0, create_weight_count: 1, build_scorer: 273835 } }, { type: ConstantScoreQuery, description: ConstantScore(DocValuesFieldExistsQuery [fieldreward_time]), time_in_nanos: 2578938, breakdown: { set_min_competitive_score_count: 0, match_count: 0, shallow_advance_count: 0, set_min_competitive_score: 0, next_doc: 0, match: 0, next_doc_count: 0, score_count: 0, compute_max_score_count: 0, compute_max_score: 0, advance: 2561666, advance_count: 24756, score: 0, build_scorer_count: 9, create_weight: 4428, shallow_advance: 0, create_weight_count: 1, build_scorer: 12844 }, children: [ { type: DocValuesFieldExistsQuery, description: DocValuesFieldExistsQuery [fieldreward_time], time_in_nanos: 923343, breakdown: { set_min_competitive_score_count: 0, match_count: 0, shallow_advance_count: 0, set_min_competitive_score: 0, next_doc: 0, match: 0, next_doc_count: 0, score_count: 0, compute_max_score_count: 0, compute_max_score: 0, advance: 914637, advance_count: 24756, score: 0, build_scorer_count: 9, create_weight: 300, shallow_advance: 0, create_weight_count: 1, build_scorer: 8406 } } ] }, { type: TermQuery, description: es_delete_flag:F, time_in_nanos: 1060002, breakdown: { set_min_competitive_score_count: 0, match_count: 0, shallow_advance_count: 0, set_min_competitive_score: 0, next_doc: 0, match: 0, next_doc_count: 0, score_count: 0, compute_max_score_count: 0, compute_max_score: 0, advance: 1020038, advance_count: 24757, score: 0, build_scorer_count: 9, create_weight: 9127, shallow_advance: 0, create_weight_count: 1, build_scorer: 30837 } } ] } ], rewrite_time: 10349, collector: [ { name: SimpleFieldCollector, reason: search_top_hits, time_in_nanos: 3358378 } ] } ], aggregations: [] }, { id: [SQYmE1nZRpiq2RL4t8yaKQ][marketing_test_drcn-t_prize_grant_record202409][1], ... }, { id: [SQYmE1nZRpiq2RL4t8yaKQ][marketing_test_drcn-t_prize_grant_record202409][2], ... } ] }这个 Profile 结果显示了您的 Elasticsearch 查询在3个分片上的详细性能分析。让我为您详细解读整体查询结构您的查询包含三个必须条件prize_type:[8 TO 8]- prize_type等于8ConstantScore(DocValuesFieldExistsQuery [fieldreward_time])- reward_time字段存在es_delete_flag:F- es_delete_flag等于F⏱️性能关键指标分片0总查询时间4,064,629 纳秒 ≈4.06毫秒处理文档数24,754 个文档主要耗时next_doc操作3.64毫秒分片1总查询时间3,870,708 纳秒 ≈3.87毫秒处理文档数24,267 个文档主要耗时next_doc操作3.46毫秒分片2总查询时间3,855,221 纳秒 ≈3.86毫秒处理文档数24,513 个文档主要耗时next_doc操作3.47毫秒性能瓶颈分析1.主要耗时操作next_doc占查询时间的85-90%这是遍历文档的主要操作advance在reward_time和es_delete_flag查询中消耗较多时间2.各子查询性能prize_type:[8 TO 8]性能最好主要耗时在next_docreward_time字段存在检查性能较差advance操作耗时严重es_delete_flag:F性能中等advance操作耗时较多问题识别主要性能问题DocValuesFieldExistsQuery性能瓶颈检查reward_time字段是否存在消耗了大量时间每个分片需要 advance 操作约2.4万次es_delete_flag查询优化空间Term查询的advance操作也有优化空间良好表现prize_type范围查询性能良好三个分片性能相对均衡3.8-4.1毫秒查询重写时间很短10-25微秒最佳实践Explain 使用时机当搜索结果不符合预期时需要理解评分模型时调试 boosting 和权重设置Profile 使用时机查询响应时间过长时需要优化复杂聚合时识别索引或映射问题生产环境注意两者都会增加查询开销避免在生产环境频繁使用建议在开发或测试环境进行调试问题public static SearchSourceBuilder page(SearchSourceBuilder builder, PageDto page) { builder.trackTotalHits(true); //builder.trackTotalHits(false); // es 分页从 0 开始 builder.from((page.getPageNum() - 1) * page.getPageSize()) .size(page.getPageSize()); return builder; } SearchSourceBuilder sourceBuilder new SearchSourceBuilder() .query(boolQuery) // 构建排序 .sort(SortBuilders.fieldSort(Constants.REWARD_TIME).order(SortOrder.DESC)) .sort(SortBuilders.fieldSort(Constants.GRANT_ID).order(SortOrder.DESC)); PageHelper.page(sourceBuilder, req.getPage()); // 构建请求 searchRequest.source(sourceBuilder); log.info(hit es [prize-grant-record] mapper, param:[{}], searchRequest); // 执行查询 SearchResponse response clientFactory.getInstance().search(searchRequest, RequestOptions.DEFAULT); return ResponseConverter.convert(response.getHits(), cls);如果builder.trackTotalHits(true)映射查询语句{ from: 45, size: 15, query: { bool: { filter: [{ range: { reward_time: { from: 2026-02-27 19:24:30, to: 2026-03-02 19:24:30, include_lower: true, include_upper: true, boost: 1.0 } } }, { term: { es_delete_flag: { value: false, boost: 1.0 } } }], adjust_pure_negative: true, boost: 1.0 } }, sort: [{ reward_time: { order: desc } }, { grant_id: { order: desc } }], track_total_hits: 2147483647 }会默认把符合查询条件的总记录数查出来!主要性能问题分析1.track_total_hits: 2147483647 问题严重程度⭐⭐⭐⭐⭐track_total_hits: 2147483647问题分析这个设置强制ES计算精确的命中总数即使有数百万条记录ES默认只返回前10,000个匹配文档的计数设置此值会显著增加查询开销对于大数据量的索引计算精确总数非常消耗资源建议解决方案// 移除或限制track_total_hits track_total_hits: false // 或者设置一个合理的上限 track_total_hits: 10000如果builder.trackTotalHits(false)映射查询语句{ from: 45, size: 15, query: { bool: { filter: [{ range: { reward_time: { from: 2026-02-27 19:24:30, to: 2026-03-02 19:24:30, include_lower: true, include_upper: true, boost: 1.0 } } }, { term: { es_delete_flag: { value: false, boost: 1.0 } } }], adjust_pure_negative: true, boost: 1.0 } }, sort: [{ reward_time: { order: desc } }, { grant_id: { order: desc } }], track_total_hits: -1 }不会查出总记录数可以使用_count查出总数结合_search查询当前页数据一起返回给前端进行分页计算总页数count和search可以使用两个线程异步一起查询。