【Elasticsearch】深度分页及其替代方案

深度分页及其替代方案

  • 1.深度分页
  • 2.为什么不推荐深度分页
    • 2.1 性能问题(核心原因)
    • 2.2 资源消耗对比
    • 2.3 实际限制
  • 3.深度分页的替代方案
    • 3.1 方案一:Search After(推荐)
      • 3.1.1 为什么 Search After 性能更高
      • 3.1.2 技术原理简化
      • 3.1.3 关键区别
      • 3.1.4 适用场景
    • 3.2 方案二:Scroll API(适用于大批量导出)
      • 3.2.1 详细解释
      • 3.2.2 类比理解
      • 3.2.3 注意事项
    • 3.3 方案三:基于时间范围的分页
    • 3.4 总结:如何选择分页方式

1.深度分页

深度分页 指的是在 Elasticsearch 中查询结果集 非常靠后的页码(例如第 1000 1000 1000 页,每页 10 10 10 条数据,即 from=10000)。它通常表现为使用 from + size 参数组合来获取远端的分页数据。例如:

GET /my_index/_search
{"from": 10000,  // 跳过前10000条"size": 10,     // 取10条"query": { ... }
}

2.为什么不推荐深度分页

2.1 性能问题(核心原因)

Elasticsearch 的分页原理是:

  • 协调节点 需要从所有分片(shard)收集满足条件的文档。
  • 计算全局排序后,临时存储 from + size 范围内的所有文档。
  • 最后返回 size 条结果。

问题

  • from 值很大时(如 from=100000),每个分片需要 先查 100000+size 条数据 到内存,再汇总排序。
  • 数据量越大,内存和 CPU 消耗呈线性增长,可能导致 内存溢出

2.2 资源消耗对比

分页方式内存消耗响应时间适用场景
浅分页(from=0低(仅缓存 size 条)毫秒级前几页数据
深度分页(from=10000高(缓存 10000+size 条)秒级甚至超时不推荐直接使用

2.3 实际限制

  • Elasticsearch 默认限制:from + size ≤ 10,000(可通过 index.max_result_window 调整,但 调高会加剧风险)。
  • 即使调高限制,性能也会急剧下降。

3.深度分页的替代方案

3.1 方案一:Search After(推荐)

原理

  • 利用上一页的排序值(如 _shard_doc 或自定义字段)作为游标。
  • 不跳过记录,直接定位到下一页的起始点。

示例

// 第一页
GET /blog_posts/_search
{"size": 10,"sort": [  // 必须包含唯一性字段(如 _id){ "publish_date": "desc" },{ "_id": "asc" }]
}// 后续页(用上一页最后一条的排序值)
GET /blog_posts/_search
{"size": 10,"search_after": ["2023-04-05", "abc123"],  // 上一页最后记录的 publish_date 和 _id"sort": [{ "publish_date": "desc" },{ "_id": "asc" }]
}

优点

  • 性能稳定(不受页码影响)。
  • 适合无限滚动、批量导出等场景。

3.1.1 为什么 Search After 性能更高

用一个生活中的例子来理解:假设你要在图书馆的 100万本书 中,每次找 10本 符合特定条件的书,并按出版日期排序。

  • 传统分页(from/size)的做法
    • 你要第 1000 页(即第 9991-10000 本书)。
    • 图书管理员必须:
      1. 先取出前 10000 本书,堆在桌子上(内存)。
      2. 排序这 10000 本,扔掉前 9990 本。
      3. 最后给你第 9991-10000 本。
    • 问题:每次翻到深页码,都要重复 “取书 + 排序 + 扔书” 的过程,桌子(内存)可能堆不下!
  • Search After 的做法
    • 你记住 当前看到的最后一本书的出版日期和编号(例如:“2023-05-01, 编号ABC123”)。
    • 下次直接告诉图书管理员:“我要比【2023-05-01, ABC123】更早的10本书”。
    • 图书管理员:
      1. 直接定位到这本书的位置(通过索引)。
      2. 往后数 10 本给你。
    • 优势:不需要临时存储前面的 9990 本书!

🚀 简而言之:Search After 快是因为它 不傻乎乎地从头数,而是像书签一样 “记住位置”,直接跳到下一页开始的地方。

3.1.2 技术原理简化

分页方式工作方式性能消耗
from/size每次从头计算,临时存储 from+size 条数据from 增大 指数级上升
search_after像书签一样记住位置,直接跳转恒定(与页码无关)

3.1.3 关键区别

  • from/size
    • 类似 “每次从第一页开始翻”
    • 计算:(from + size) × 分片数 → 内存爆炸 💥
  • search_after
    • 类似 “记住看到哪里,接着往下读”
    • 计算:size × 分片数内存恒定 📊

3.1.4 适用场景

  • from/size
    • 前几页(如首页、搜索结果前 10 条)
  • search_after
    • 无限滚动(如微博、朋友圈)
    • 深度分页(如第 100 页+)

3.2 方案二:Scroll API(适用于大批量导出)

原理

  • 创建快照(snapshot),保持查询上下文。
  • 逐批获取数据,类似数据库游标。

示例

// 1. 初始化 Scroll(保留1分钟)
GET /blog_posts/_search?scroll=1m
{"size": 100,"query": { "match_all": {} }
}// 2. 后续获取(用返回的 scroll_id)
GET /_search/scroll
{"scroll": "1m", "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gB..."
}// 3. 最后手动清理
DELETE /_search/scroll
{"scroll_id": "DXF1ZXJ5QW5kRmV0Y2gB..."
}

优点: 适合非实时、大数据量导出(如报表生成)。

缺点

  • 不支持实时数据(快照期间数据变化不会反映)。
  • 占用服务器资源,用完需手动清理(DELETE /_search/scroll)。

3.2.1 详细解释

  • scroll=1m 的含义
    • 1m = 1 分钟(时间单位,类似 30s = 30秒2h = 2小时
    • 表示 Elasticsearch 会保留这次 Scroll 查询的上下文(如排序结果、快照数据)1 分钟。
    • 超时后,Scroll 会自动失效,资源被释放。
  • 为什么需要设置超时?
    • Scroll 会占用服务器内存和资源,长时间不释放可能导致性能问题。
    • 设置超时(如 1m)是让 Elasticsearch 自动清理 不再使用的 Scroll 查询。
  • 如何调整超时?
    • 根据数据量调整,例如:
      • 大数据导出:scroll=5m 5 5 5 分钟)
      • 小批量查询:scroll=30s 30 30 30 秒)
  • 续期 Scroll
    如果处理时间较长,可以在每次请求时刷新超时时间:
    GET /_search/scroll
    {"scroll": "1m",  // 重新设置为1分钟"scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVY..."
    }
    

3.2.2 类比理解

把 Scroll 想象成图书馆的 “临时书架”

  • 你告诉图书管理员:“我需要 1 分钟(scroll=1m)来挑书”。
  • 1 分钟内,书架上的书(查询结果)保持不变,你可以慢慢选。
  • 超时后,图书管理员会把书架清空(释放资源)。
  • 如果你需要更多时间,可以喊:“再给我 1 分钟!”(续期 Scroll)。

3.2.3 注意事项

  • 不要滥用长超时(如 scroll=1h),否则可能导致集群内存压力。
  • 用完务必清理(即使未超时):
    DELETE /_search/scroll
    {"scroll_id": "DXF1ZXJ5QW5kRmV0Y2gB..."
    }
    
  • Scroll 适用于离线任务(如导出数据),不适用于实时分页。

3.3 方案三:基于时间范围的分页

原理

  • 用时间字段(如 publish_date)作为分页条件。
  • 每页查询限定时间范围。

示例

GET /blog_posts/_search
{"size": 10,"query": {"range": {"publish_date": { "lte": "2023-03-01" }  // 第二页改为 "lte": "上一页的最小日期"}},"sort": [ { "publish_date": "desc" } ]
}

适用场景

  • 按时间线分页(如新闻列表)。

3.4 总结:如何选择分页方式

场景推荐方案原因
用户前端分页(前几页)from + size简单易用,性能可接受
深度分页(如第 100 100 100 页)Search After避免内存爆炸,性能稳定
大数据量导出Scroll API适合离线处理,但需注意资源释放
按时间滚动时间范围查询利用业务字段天然分页

关键建议

  • 禁止生产环境使用大 from 值(如 from=100000)。
  • 若必须调整 index.max_result_window,需评估集群资源。
  • Search After 是深度分页的最佳实践,兼容大多数场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913355.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913355.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文阅读笔记——VGGT: Visual Geometry Grounded Transformer

VGGT 论文 输入是 N 个 RGB 图像 I i ∈ R 3 H W I_i\in\mathbb{R}^{3HW} Ii​∈R3HW 的序列 ( I i ) i 1 N (I_i)^N_{i1} (Ii​)i1N​,观察相同 3D 场景。 VGGT 的 Transformer 是一个映射函数,将此序列映射为一组对应的 3D 标注, f ( …

【嵌入式电机控制#11】PID控制入门:对比例算法应用的深度理解

接下来内容需要数学功底,并且有现成结论的内容不做推导,重在讲解工程实践中的方法论,建议控制类专业或学习过相关理论的人阅读 一、开闭环系统 (1)开环控制系统:被控对象输出对控制器的输出没有影响 &…

多视图几何:本质矩阵与基础矩阵

文章目录 1. 前置知识1.1. 向量叉乘1.2. 混合积1.3. 引理证明 2. 本质矩阵3. 基础矩阵4. 应用例子 1. 前置知识 1.1. 向量叉乘 假设 a ( a x a y a z ) \mathbf{a} \begin{pmatrix} a_x \\ a_y \\ a_z \end{pmatrix} a ​ax​ay​az​​ ​ 以及 b ( b x b y b z ) \mat…

Hive集群之间迁移的Linux Shell脚本

新旧 Hive 集群之前数据迁移单表脚本 migrate_hive_single_table.sh #!/bin/bash#配置参数 OLD_NAMENODE"hdfs://<old-namenode>:<old-port>" EXPORT_PATH"/tmp/hive-export/dm" NEW_DB"dm_events" TABLE_NAME"dm_usereventfi…

新时代的开始,华为开源仓颉编程语言!

7月30日&#xff0c;华为即将开源自研的仓颉编程语言。 仓颉这个名字很有意思。传说中的仓颉创造了汉字&#xff0c;开启了中华文明的文字时代。华为用这个名字&#xff0c;体现了对中华文化的致敬。从2020年开始研发&#xff0c;到去年首次亮相&#xff0c;再到现在的全面开源…

【python实用小脚本-128】基于 Python 的 Hacker News 爬虫工具:自动化抓取新闻数据

引言 在技术社区中&#xff0c;Hacker News 是一个汇聚最新技术文章和讨论的热门平台。许多开发者和技术爱好者依赖它来获取行业动态和前沿资讯。然而&#xff0c;手动浏览和筛选这些文章可能耗时且低效。本文将介绍一个基于 Python 的 Hacker News 爬虫工具&#xff0c;它能够…

mac 电脑安装Homebrew来安装npm与node成功后,安装nvm的流程

文章目录 前言一、卸载node(如果没下载可以忽略这步)1.官网下载安装包的2. homebrew安装的 二、安装Homebrew(1) 命令安装&#xff08;2&#xff09;出现上面提示&#xff0c;执行对应的命令&#xff08;3&#xff09;校验是否安装成功 三&#xff1a;安装node&#xff08;Home…

根据无人机倾斜摄影osgb做的3dmax模型3dtiles制作,导出.b3dm加载到谷歌地图cesiumlab

根据无人机倾斜摄影osgb做的3dmax模型3dtiles制作&#xff0c;导出.b3dm加载到谷歌地图cesiumlab 根据无人机倾斜摄影osgb做的3dmax模型3dtiles制作&#xff0c;导出.b3dm加载到谷歌地图cesiumlab

Yocto项目:嵌入式Linux开发的“万能烹饪手册”

目录 一.Yocto是什么? 二.Yocto如何运作&#xff1f; 2.1 三大核心工具 2.2 实例 三.为什么开发者爱用Yocto&#xff1f; 3.1 ​自由定制&#xff0c;拒绝“全家桶”​​ 3.2 跨平台支持&#xff1a;从x86到火星芯片​ 3.3 工业级可靠性​ PetaLinux是Xilinx官方推出的…

【nosql】有哪些非关系型数据库?

非关系型数据库Nosql 分类 键值存储 (Key-Value Store): 代表: Redis, DynamoDB, RocksDB, etcd核心优势: 极致简单、超高读写性能&#xff08;尤其内存型&#xff09;、高吞吐。场景: 缓存、会话存储、配置、计数器、分布式协调、简单消息队列。 列式 / 宽列存储 (Wide-Colu…

Redis存储Cookie实现爬虫保持登录 requests | selenium

前言 前面已经介绍了requests和selenium这两种方式的基础知识和模拟登录,但是我们需要每次都进行登录,这明显是很麻烦并且不合理的,所以这次我分享一下怎么可以让我们的程序进行一次登录之后,和普通浏览器一样下次不进行登录直接进行对网站数据的爬取 下面的我分享的内容需要…

leetcode:474. 一和零[01背包][动态规划]

学习要点 给定背包容量&#xff0c;装满背包最多有多少个物品深入理解01背包深入理解动态规划 题目链接 474. 一和零 - 力扣&#xff08;LeetCode&#xff09; 题目描述 解法:01背包 class Solution { public:int findMaxForm(vector<string>& strs, int m, int …

UE5 使用过程遇到的问题

切换缓存位置 进入界面&#xff0c;选择-编辑-编辑器偏好设置搜索缓存&#xff0c;找到通用全局&#xff0c;修改本地DCC路径到要切换的位置 闪退报错 Fatal: Failed to get dll export function: cuvidGetDecoderCaps [NVDEC] 因为NVIDIA驱动没有卸载干净&#xff0c;使用D…

2025 BSidesMumbaiCTF re 部分wp

XORyy 附件拖入ida。明文 idkwhattonamethis 附件拖入ida 前三个函数都是检查环境&#xff0c;跳过即可 长度为5&#xff0c;可以根据flag格式求解。脚本。尽管多解但是可能的结果很少 Diff_EQ 附件拖入ida z3求解等式&#xff0c;脚本。无反调试的情况下本地可以验证&#xff…

图灵完备之路(数电学习三分钟)----逻辑与计算架构

经过前面几节的学习&#xff0c;我们已经有了简单的数电知识&#xff0c;下面&#xff0c;我们将正式进入设计简单图灵完备机的工作&#xff0c;首先&#xff0c;我们要设计出具有逻辑运算与计算功能的简单结构&#xff1a; 1.逻辑架构 首先&#xff0c;该架构能实现多种逻辑…

【C++笔记】AVL树的深度剖析

【C笔记】AVL树的深度剖析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录【C笔记】AVL树的深度剖析前言一. AVL树的概念二.AVL树的实现2.1 AVL树的结构2.2 AVL树的插入2.3 平衡因子更新三.旋转3.1旋转的原则3.2右单旋3.3左单…

支持向量机(SVM)在肝脏CT/MRI图像分类(肝癌检测)中的应用及实现

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…

DeepSeek扫雷游戏网页版HTML5(附源码)

用DeepSeek帮忙生成一个网页版的扫雷游戏&#xff0c;效果非常棒&#xff0c;基于HTML5实现&#xff0c;方便运行。 提示词prompt 帮我做一个网页版的 html5 扫雷游戏游戏功能说明 游戏难度&#xff1a; 1 简单&#xff1a;1010 格子&#xff0c;10个地雷 2 中等&#xff1a;16…

Day53GAN对抗生成网络思想

生成对抗网络&#xff08;GAN&#xff09;是深度学习领域的一种革命性模型&#xff0c;由Ian Goodfellow等人于2014年提出。其核心思想源于博弈论中的零和博弈&#xff0c;通过两个神经网络&#xff08;生成器和判别器&#xff09;的对抗性训练&#xff0c;实现数据的高质量生成…

meilisearch-轻量级搜索引擎

meilisearch是一款开源的轻量级搜索引擎&#xff0c;相比于elasticsearch等重量级搜索引擎&#xff0c;meilisearch注重数据搜索&#xff0c;从而而省去了其它不必要的功能&#xff08;如支持聚合分析、分布式搜索等特性&#xff09;&#xff0c;以便于快速上手开发和构建应用。…