近日,中国科学院昆明动物研究所依托“模式动物表型与遗传研究国家重大科技基础设施(灵长类设施)”,接连在灵长类动物模型研究领域取得重要进展。建立全球首个...
2026-07-03 38
ES分页查询性能很差,使用from/size方式检索居然需要10分钟!

这是一个非常典型的问题,尤其在大数据量、多索引场景下特别常见。
我会从问题根源出发,逐步分析原因,并给出详细的优化方案和实现代码,希望能帮到遇到类似问题的朋友。
一、问题引出:为什么查询这么慢?
群友的场景是这样的:
他们通过ES的范围查询(range query)和排序(sort)从多个索引(applcation*)中分页检索数据,DSL如下:
curl -X POST "http://elasticsearch.elastic:9201/applcation*/_search" -H 'Content-Type: application/json' -d '{ "from": 0, "query": { "bool": { "filter": { "range": { "timestamp": { "from": "1743609600000", "include_lower": true, "include_upper": false, "to": "1744214400000" } } } } }, "size": 100, "sort": [ { "timestamp": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } }, { "_uuid_": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } } ]}'这个查询的目标很简单:
但问题来了:查询耗时高达10分钟(磁盘原因如下图说明,可以降到2分钟,但依然有很大优化空间)!

——笔者补充说明:Elastic 集群最好独立部署!
更夸张的是,命中数据量达到了6亿多条 。这显然不是正常现象,我们得找到性能瓶颈。
二、问题分析:性能瓶颈在哪里?
通过DSL和聊天记录,我梳理出以下几个关键问题:
1、分页方式问题:from/size的深分页缺陷
ES的from/size分页是通过跳过前from条记录来实现的。当from很大时(比如翻到第10000页),ES需要在所有匹配的6亿条数据中排序后跳过大量记录,这会导致内存和计算资源的极大浪费。
当前from=0还不算深分页,但size=100结合6亿条命中数据,依然会触发大量数据扫描和排序。
2、数据范围过大:7天的数据量爆炸
时间戳范围从1743609600000(2025-03-01)到1744214400000(2025-03-08),整整7天。

以6亿条命中数据计算,每天平均约8571万条,数据量非常恐怖。
ES需要扫描整个范围内的数据,即使加了filter,依然要处理海量记录。
3、多索引查询:通配符的性能隐患
使用applcation*通配符查询多个索引,可能涉及几十甚至上百个索引。
每个索引都需要独立扫描、分片计算,最终再合并结果,性能开销自然翻倍。
4、单次返回数据量:size=100的影响
每次返回100条数据不算多,但如果单条数据体积较大(比如包含复杂嵌套字段或大文本),网络传输和序列化开销会显著增加。
5、排序开销:双字段排序的代价
按timestamp和_uuid_排序需要对所有命中数据构建排序堆,
尤其在数据量大时,内存和CPU消耗会非常高。
总结一下:深分页+大范围数据+多索引+排序 ,这几大因素叠加,导致查询性能崩盘。接下来,我们探讨优化方案。
三、方案探讨:如何破局?
针对上述问题,我提出了三大优化方向,并结合ES的最佳实践,逐步解决问题:
1、减少单次返回数据量
2、缩小查询时间范围
3、替换分页方式:从from/size到search_after
4、优化索引管理:引入别名机制
综合来看,这四个方向是层层递进的:先从简单调整(size和时间范围)入手,再到技术升级(search_after和别名)。
下面是具体实现。
四、方案实现:优化后的DSL与步骤
步骤1:调整size和时间范围
先尝试最简单的优化,将size从100改为10,时间范围从7天缩小到1天:
POST /applcation*/_search{"from": 0,"query": { "bool": { "filter": { "range": { "timestamp": { "from": "1743609600000", "include_lower": true, "include_upper": false, "to": "1743696000000" // 缩短为1天 } } } } },"size": 10, // 减少返回条数"sort": [ { "timestamp": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } }, { "_uuid_": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } } ]}效果推论:假设1天数据量为8571万条,命中量减少到原来的1/7,性能会有明显提升。
步骤2:切换到search_after
如果用户必须查询 7 天数据,且需要翻页,我们改用search_after。首次查询如下:
POST /applcation*/_search{"from": 0,"query": { "bool": { "filter": { "range": { "timestamp": { "from": "1743609600000", "include_lower": true, "include_upper": false, "to": "1743696000000" // 缩短为1天 } } } } },"size": 10, // 减少返回条数"sort": [ { "timestamp": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } }, { "_uuid_": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } } ]}返回结果中,记录最后一条数据的排序值,比如:
{ "hits": { "hits": [ {"_source": {...}, "sort": ["1744214399999", "uuid123"]}, ... {"_source": {...}, "sort": ["1744214380000", "uuid456"]} // 最后一条 ] }}下一页查询使用search_after:
POST /applcation*/_search{"query": { "bool": { "filter": { "range": { "timestamp": { "from": "1743609600000", "include_lower": true, "include_upper": false, "to": "1744214400000" } } } } },"size": 10,"search_after": ["1744214380000", "uuid456"], // 使用上一页最后一条的sort值"sort": [ { "timestamp": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } }, { "_uuid_": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } } ]}注意 :search_after要求排序字段具有唯一性,这里用timestamp和_uuid_组合,确保结果稳定。
步骤3:引入别名机制
假设数据按天分索引(如applcation-2025-03-01),我们可以创建按天的别名:
POST /_aliases{ "actions": [ { "add": { "index": "applcation-2025-03-01", "alias": "applcation-day-20250301" } }, { "add": { "index": "applcation-2025-03-02", "alias": "applcation-day-20250302" } } ]}查询时指定别名:
POST /applcation-day-20250301/_search{"query": { "bool": { "filter": { "range": { "timestamp": { "from": "1743609600000", "include_lower": true, "include_upper": false, "to": "1743696000000" } } } } },"size": 10,"sort": [ { "timestamp": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } }, { "_uuid_": { "missing": "_last", "order": "desc", "unmapped_type": "keyword" } } ]}效果 :只查询单日索引,扫描范围大幅缩小。
五、总结
从10分钟到秒级的蜕变通过以上优化,我们从多个角度解决了性能问题:
实际效果如何?以6亿条数据为例:
最后给大家的建议:
希望这篇文章能帮到大家,有问题欢迎随时交流!
作者丨铭毅天下
来源丨公众号:铭毅天下Elasticsearch(ID:elastic999)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
相关文章
近日,中国科学院昆明动物研究所依托“模式动物表型与遗传研究国家重大科技基础设施(灵长类设施)”,接连在灵长类动物模型研究领域取得重要进展。建立全球首个...
2026-07-03 38
无需打开直接搜索微信:本司针对手游进行,选择我们的四大理由: 1、软件助手是一款功能更加强大的软件!无需打开直接搜索微信: 2、自动连接,用户只要开启...
2026-07-03 12
现在人们打棋牌麻将谁不想赢?手机微乐麻将必赢神器但是手机棋牌麻将是这么好赢的吗?在手机上打棋牌麻将想赢,不仅需要运气,也需要技巧。掌握的棋牌麻将技巧就...
2026-07-03 89
您好:这款游戏是可以开挂的,软件加微信【添加图中微信】确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,总是好牌,而且好像能看到其他人...
2026-07-03 7
现在人们打棋牌麻将谁不想赢?手机微乐麻将必赢神器但是手机棋牌麻将是这么好赢的吗?在手机上打棋牌麻将想赢,不仅需要运气,也需要技巧。掌握的棋牌麻将技巧就...
2026-07-03 65
2025年末的手机市场格外热闹,11月25日华为正式发布Mate 80系列旗舰机型,并于11月28日开启发售,相关话题迅速席卷社交平台与数码论坛。在年...
2026-07-03 42
这是荷兰历史上最严重的航空灾难, 一架满载货物的波音747,刚起飞几分钟,就突发意外,飞机失控俯冲。机组拼尽全力,好不容易稳住飞机,却依旧没逃过坠机的...
2026-07-03 14
ES分页查询性能很差,使用from/size方式检索居然需要10分钟!这是一个非常典型的问题,尤其在大数据量、多索引场景下特别常见。我会从问题根源出发...
2026-07-03 9
发表评论