Elasticsearch性能优化:深分页问题详解及高效解决方案
原文地址: https://88box.top 生成时间: 2026-05-20 01:00:25
Elasticsearch性能优化实战:深分页问题原理、影响与解决方案全解析 - hey99 知识搜索引擎
精选文章
Elasticsearch性能优化实战:深分页问题原理、影响与解决方案全解析
在Elasticsearch(ES)的实际生产应用中,分页查询是最基础、最常用的功能,比如列表展示、数据导出、滚动加载等场景。但当分页深度达到一定量级(如查询第10000页、每页10条数据)时,会触发ES的深分页问题,直接导致查询性能暴跌、内存溢出、节点不稳定,甚至整个集群宕机。很多开发者对分页的风险认知不足,在大数据量场景下盲目使用,最终引发线上故障。本文将从深分页的定义、底层原理、负面影响、解决方案四个维度,结合流程图和实战代码,全方位解析ES深分页问题,帮你彻底规避性能陷阱。ES默认使用from。
更新于 2026-05-19 16:58
Elasticsearch性能优化实战:深分页问题原理、影响与解决方案全解析
前言
一、Elasticsearch 深分页问题核心认知
1.1 什么是深分页?
1.2 深分页底层执行原理(流程图详解)
二、深分页带来的严重影响
三、Elasticsearch 深分页三种解决方案(有序详解)
方案1:修改 max_result_window 参数(临时方案,不推荐)
3.1.1 适用场景
3.1.2 操作命令
3.1.3 缺点
方案2:Scroll 滚动查询(适合全量导出数据)
3.2.1 核心原理
3.2.2 适用场景
3.2.3 实战代码
3.2.4 缺点
方案3:search_after 实时深分页(生产环境首选推荐)
3.3.1 核心原理
3.3.2 适用场景
3.3.3 实战代码
3.3.4 优点
3.3.5 限制
四、三种分页方案全方位对比总结
五、生产环境最佳实践建议
六、总结
总结
🌺The Begin🌺点点关注,收藏不迷路🌺
前言
在Elasticsearch(ES)的实际生产应用中,
分页查询
是最基础、最常用的功能,比如列表展示、数据导出、滚动加载等场景。但当分页深度达到一定量级(如查询第10000页、每页10条数据)时,会触发ES的
深分页问题
,直接导致查询性能暴跌、内存溢出、节点不稳定,甚至整个集群宕机。
很多开发者对
from + size
分页的风险认知不足,在大数据量场景下盲目使用,最终引发线上故障。本文将从
深分页的定义、底层原理、负面影响、解决方案
四个维度,结合流程图和实战代码,全方位解析ES深分页问题,帮你彻底规避性能陷阱。
一、Elasticsearch 深分页问题核心认知
1.1 什么是深分页?
ES默认使用
from + size
实现分页查询:
from
:表示从第几条数据开始查询(偏移量)
size
:表示每页查询多少条数据
示例
:查询第10000页,每页10条数据
GET
/
order
/
_search
{
"from"
:
99990
,
"size"
:
10
}
深分页定义
:当
from
值非常大,超出ES默认限制(默认
max_result_window = 10000
)时,就属于
深分页
。
简单理解:
查询越靠后的数据,分页越深,性能越差
。
1.2 深分页底层执行原理(流程图详解)
ES是分布式搜索引擎,数据会分片存储在不同节点,深分页的性能损耗核心来源于
分布式数据聚合
。
核心原理说明
:
协调节点接收请求,转发给索引的
所有分片
;
每个分片必须查询并返回
from + size
条数据(如示例中每个分片返回10010条);
协调节点汇总
所有分片
的数据,进行全局排序;
最终只截取
size
条数据返回,
99%的中间数据全部丢弃
;
分页越深,分片越多,内存和网络损耗呈指数级增长。
二、深分页带来的严重影响
深分页不是简单的查询慢问题,而是
集群级别的性能风险
,主要影响如下:
查询性能急剧下降
分页越深,需要聚合、排序的数据量越大,查询耗时从毫秒级飙升至秒级、分钟级。
大量占用网络带宽
各分片与协调节点之间传输海量无用数据,占用集群网络带宽,影响其他业务查询。
触发内存溢出(OOM)
协调节点需要在内存中存储、排序大量数据,极易导致JVM内存溢出,节点宕机。
触发ES默认保护机制
ES默认限制
max_result_window=10000
,超过后直接报错,拒绝查询:
Result window is too large... Please use scroll or search_after
集群稳定性雪崩
大量深分页请求并发执行,会导致整个ES集群CPU、内存、网络满载,服务不可用。
三、Elasticsearch 深分页三种解决方案(有序详解)
ES官方提供了
三种分页方案
,针对不同业务场景,解决深分页问题:
方案1:修改 max_result_window 参数(临时方案,不推荐)
3.1.1 适用场景
分页深度
轻度超标
(如1万~5万)
数据量小、并发低的非核心业务
3.1.2 操作命令
PUT
/
order
/
_settings
{
"index.max_result_window"
:
50000
}
3.1.3 缺点
只是解除限制,
没有解决性能问题
;
深度越大,风险越高,不能从根本解决深分页。
方案2:Scroll 滚动查询(适合全量导出数据)
3.2.1 核心原理
Scroll 会生成
数据快照
,一次性查询全量数据,分批返回,不实时,不跳页。
3.2.2 适用场景
全量数据导出、备份、离线计算
不需要实时数据,不需要随机跳页
3.2.3 实战代码
第一步:初始化滚动查询,获取scroll_id
GET
/
order
/
_search
?
scroll
=
1m
{
"size"
:
100
,
"query"
:
{
"match_all"
:
{
}
}
}
第二步:循环使用scroll_id获取数据
GET
/
_search
/
scroll
{
"scroll"
:
"1m"
,
"scroll_id"
:
"FGluY2x1ZGVfY29udGV4dC..."
}
3.2.4 缺点
生成快照,
数据不实时
;
占用上下文资源,不适合高并发、用户端使用。
方案3:search_after 实时深分页(生产环境首选推荐)
3.3.1 核心原理
基于
上一页的最后一条数据
定位下一页,
无偏移量查询
,性能极高,支持实时数据。
3.3.2 适用场景
app/网页列表下拉加载更多
高并发、实时性要求高的深分页场景
生产环境标准解决方案
3.3.3 实战代码
第一步:第一页查询,获取排序字段值
GET
/
order
/
_search
{
"size"
:
10
,
"sort"
:
[
{
"id"
:
"asc"
}
,
{
"create_time"
:
"asc"
}
]
}
第二步:使用search_after查询下一页
GET
/
order
/
_search
{
"size"
:
10
,
"search_after"
:
[
100
,
1620000000000
]
,
"sort"
:
[
{
"id"
:
"asc"
}
,
{
"create_time"
:
"asc"
}
]
}
3.3.4 优点
无偏移量,性能几乎无衰减;
支持实时数据;
不占用内存上下文,集群无压力。
3.3.5 限制
不支持
随机跳页
(如直接跳转到第100页),只能顺序翻页。
四、三种分页方案全方位对比总结
对比维度
from+size(普通分页)
Scroll(滚动查询)
search_after(推荐)
实现难度
简单
中等
中等
性能
深度越大越差
较好
优秀,无衰减
实时性
实时
非实时(快照)
实时
跳页支持
支持
不支持
不支持
适用场景
浅分页(前1000条)
全量导出、备份
下拉加载、高并发深分页
生产推荐
否
仅导出使用
是
五、生产环境最佳实践建议
禁止前端使用随机跳页
改用
下拉加载更多
,适配
search_after
方案。
严格限制from+size分页深度
不修改
max_result_window
,默认10000条足够满足浅分页。
数据导出专用Scroll
全量数据导出、ETL同步场景,单独使用Scroll,不影响线上业务。
排序字段必须唯一
使用
search_after
时,排序字段必须唯一(如ID+时间),避免数据重复/丢失。
六、总结
Elasticsearch 深分页问题的核心根源是
分布式架构下的分片数据聚合机制
,分页越深,性能损耗越大。
from+size
仅适合
浅分页
,绝对不能用于深分页;
Scroll 适合
全量数据导出
,不支持实时和跳页;
search_after
是
生产环境深分页最优解
,高性能、实时、无集群风险;
业务设计规避随机跳页,是解决深分页问题的根本手段。
掌握本文方案,可彻底解决ES深分页导致的性能、内存、稳定性问题,保障集群安全运行。
总结
深分页本质
:
from
过大,分片聚合大量无用数据,导致性能暴跌、内存溢出;
核心风险
:查询超时、OOM、集群雪崩,ES默认限制10000条防护;
最优方案
:生产环境
优先使用search_after
,导出数据用Scroll;
业务原则
:前端避免随机跳页,采用下拉加载适配深分页方案。
🌺The End🌺点点关注,收藏不迷路🌺
查看原文
🏷 标签: Elasticsearch, 深分页优化, search_after, Scroll API, 性能调优