前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

一、数据库

1、关系型数据库

1)什么是(SQL)关系型数据库:

关系型数据库指的是使用关系模型(二维表格模型)来组织数据的数据库, 关系模型可以简单理解为二维表格模型,而一个关系型数据库就是由二维表及其之间的关系(如主键和外键)进行连接。

常见的有:OracleMySqlMicrosoft SQL ServerSQLitePostgreSQL

2)优势

1、数据结构清晰,易于理解和维护。

2、 数据一致性和完整性高,通过 ACID 事务保证数据的一致性;

3、支持复杂查询,通过 SQL 语言可以方便地进行多表联合查询;

3)不足

随着互联网企业的不断发展,数据日益增多,因此关系型数据库面对海量的数据会存在很多的不足。

1、数据读写性能有限,特别是在处理大规模高并发数据时。

2、扩展性相对较差,不易应对快速变化的数据模型。

3、 固定的数据结构可能导致灵活性不足,关系型数据库的数据模型定义严格,无法快速容纳新的数据类型(需要提前知道需要存储什么样类型的数据)

4)代表

Oracle:大型关系数据库管理系统,提供企业级的数据管理解决方案。

MySQL:开源的关系型数据库,广泛应用于各种Web应用中。

SQL Server:微软开发的关系数据库管理系统,提供丰富的功能和强大的性能。

2、非关系型数据库

1)什么是(NOSQL)非关系型数据库:

非关系型数据库(NoSQL)泛指非关系型的、分布式的、且一般不保证遵循 ACID 特性的数据存储系统。它不基于关系模型,而是基于键值对、文档、图形或列式存储等方式。

非关系型数据库又被称为 NoSQLNot Only SQL ),意为不仅仅是 SQL。通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定,常用于存储非结构化的数据。

非关系型数据库存储数据的格式可以是 key- value 形式、文档形式、图片形式等。使用灵活,应用场景广泛,而关系型数据库则只支持基础类型

2)优势

1、 高并发读写性能,适用于大规模数据处理。

2、 海量数据的维护和处理非常轻松,成本低。

3、数据结构灵活,无需预定义表结构。

4、水平扩展性好,易于构建分布式系统。

3)不足

1、不同的非关系型数据库之间差异较大,选择时需要考虑具体需求。

1、非关系数据库没有事务处理,无法保证数据的完整性和安全性。适合处理海量数据,但是不一定安全。

3、缺乏统一的查询语言,查询和处理的复杂度可能增加。

4)代表

1、键值数据库-Redis:内存数据结构存储,可以用作数据库、缓存和消息中间件

2、列族数据库-**HBase **基于列存储的分布式数据库,适用于大规模的结构化数据存储

3、文档数据库- MongoDB 基于文档的 NoSQL 数据库,支持动态模式,适用于快速变化的数据模型

4、 图形数据库:Neo4jInfoGrid

二、OLTPOLAP

OLTP·(联机事务处理)应用的场景,其存储的主要是与业务直接相关的数据,强调准确、低时延、高并发,如果没有特别强调,基本上数据库里只会去存储与业务相关的数据。

OLAP(联机分析处理)是数据仓库系统的主要应用,其支持的对象只要是面向分析场景的应用,提供结构化的、主题化的数据提供给运营,做业务反馈和辅助决策用,同时,有些场景下,也可以由数据仓库对业务进行支持。

  OLTP (联机事务处理) OLAP(联机分析处理)
使用场景 在线业务服务 数据分析、挖掘、机器学习
涉及数据量 当前正在发生的业务数据 历史存档数据
事务和数据完整性 对事务和数据一致性要求高 对实物能力没有要求,数据不一致也可以重建
功能使用需求 简单增删改查,要求响应时间极短 复杂的聚合和多数据源关联,查询时间可到分钟,小时,天
并发要求 高并发 低并发
实现方案 事务、索引、存储计算耦合 大量 SCAN、列式存储,存储计算可以分离
可用性要求 非常高 不高
技术典范 MYSQL Clickhouse
数据结构 关系数据库。 使用多维(多维数据集)或关系数据库。

1、理解篇

1)场景

场景:跟开发沟通需求时,可能会听到“这个(数据)数据库没存,取不到……”、“我这边没这张表,去找业务的人要……”、“这个(数据)在日志里,要的话提个需求给我……”、“我们两边存储的逻辑不一样,数据结果当然不一样啊”、如果你也碰到过这种情况,这节内容对你有用。这节内容将围绕数据从产生-入库-分析环节,数据库和数据仓库的区别和作用。

产品的使用者在前端做交互会产生各种行为数据,略作区分的话,可以分为行为数据,和业务数据。

⬤ 行为数据是指用户的点击、浏览等操作数据;

⬤ 业务数据本质上也是行为数据,能被叫作业务数据,是因为与产品的业务目标挂钩。如用户的注册行为、订单行为(也是需要与服务端做交互产生的数据)。

为了保证对业务的快速响应和支持,针对产品和业务功能有一个直接的数据库与之进行交互,OLTP是与功能、业务强相关的事务查询系统,要保证高并发场景下低时延的查询和处理效率,因此对 CPU 的性能要求较高。而直接存储与功能和业务直接相关的地方,就叫数据库,一般是服务端开发的同事来负责。

数据库主要为在线业务服务。如果是分析场景需要查询数据,涉及到从业务数据库取数据,就意味着会影响业务数据库对业务的支持。量小还好,量大或者查询比较复杂,服务端的同事就会担心影响到线上业务,或者把业务数据库查“崩”了影响线上业务,因此非常 nice地拒绝你的需求。

企业在经过初期的市场验证阶段后,会开始寻求从数据中找到下一步发展的方向,直接从业务数据库获取数据限制颇多,因此这时候就需要搭建数据仓库体系了。

数据仓库是独立于业务数据库之外的一套数据存储体系OLAP 是数据仓库系统的主要应用,能够支持复杂的分析操作,与数据库需要直接直接线上业务不同,数据仓库侧重于分析决策,提供直观的数据查询结果。(当然数据仓库也是可以支持线上业务的,比如电商场景下常见的,根据用户行为做商品推荐。用户的行为数据存进数仓后,进行实时计算,然后将算法模型计算出的推荐结果发给业务端做展示。)。

企业初期阶段,全部数据存储、业务应用支持和分析支持都是交给业务数据库来做。相比于对分析应用的支持,数据库肯定会先确保对前端业务的支持。因此在响应分析场景的需求时,速率和数据完整度往往不尽如人意。

2)过程

Q1、这个(数据)数据库没存,取不到……:

答:如果行为数据没有与业务直接关联,而且产品经理也没有要求记录,开发们大概率是不会做对应的数据采集的,所以有了上面回答。这时候要拿小本本记一下,告诉开发gg:“谢谢gg,下次我就提这个数据的采集需求!”

Q2. “我这边没这张表,去找业务的人要……”:

答:如果你们已经有了数据仓库,和 BI 应用的话,开发那边大概率会拆分一组叫【大数据】的人,他们主要负责数据仓库的建设和 B I数据产品的支持。但有的数据存在了业务数据库,没有同步到数据仓库时,你去问大数据同事要数据的时候,他们就会这样温柔地回应你。

Q3. “这个(数据)在日志里,要的话提个需求给我……”:

答:只要用户与服务端有交互(如发起了订单、注册成功等行为),业务数据库基本会将其全部记录下来,是一条条的明细数据。所以如果你提的需求恰好有,在日志里,他们需要从日志里“捞”出对应的数据,然后清洗计算之后,才能把数据拿出来,因此需要你提一个需求,要不然主管又要问他今天干啥了。

注:需注意,明细日志一般不会永久保留,过一段时间后,已经没有依赖这些数据的应用时,这些数据就会被删掉,保留时长不同公司不一样,所以上述场景发生在数据还在的前提下。

2、OLAP

OnLine Analytical Processing:联机分析处理

olap是传统的关系型数据库的主要应用,主要基本的、日常的事务处理,例如银行交易。目前市面上主流的开源 olap数据库引擎包含:HiveHawqPrestoKylinImpalaSparksqlDruidClickhouseGreeplum等。

1)多维 MOLAP ( Multi-dimensional OLAP )

多维 OLAP 基于直接支持多维数据和操作的本机逻辑模型。数据物理上存储在多维数组中, 并且使用定位技术来访问它们。。

这种方式可以快速地响应用户的多维分析请求,提供高效的查询和分析性能,MOLAP 一般会根据用户定义的数据维度、度量(也可以叫指标)在数据写入时生成预聚合数据;Query 查询到来时,实际上查询的是预聚合的数据而不是原始明细数据,在查询模式相对固定的场景中,这种优化提速很明显。

MOLAP 的优点和缺点都来自于其数据预处理 ( pre-processing ) 环节。数据预处理,将原始数据按照指定的计算规则预先做聚合计算,这样避免了查询过程中出现大量的即使计算,提升了查询性能。

但是这样的预聚合处理,需要预先定义维度,会限制后期数据查询的灵活性;

如果查询工作涉及新的指标,需要重新增加预处理流程,损失了灵活度,存储成本也很高。同时,这种方式不支持明细数据的查询,仅适用于聚合型查询(如:sum,avg,count)。

使用场景:多维 OLAP 主要适用于需要对数据进行多维分析的场景,如市场分析、销售分析等。在这些场景中,用户可以通过多维度的视角,深入剖析数据,挖掘潜在的业务价值。

优点: 多维 OLAP 的优点在于其查询和分析性能高,可以支持复杂的多维分析操作

缺点:由于数据存储在多维数组中,可能会占用较多的存储空间。此外,对于非预定义的多维分析需求,可能需要重新构建多维数组,增加了操作的复杂性。

代表:主要有 DruidKylin 。这些系统都是基于直接支持多维数据和操作的本机逻辑模型,它们在数据写入时生成预聚合数据,从而在查询时提高查询速度,尤其在查询模式相对固定的场景中,这种优化提速效果尤为明显。

2)关系型 OLAP (Relational OLAP)

关系型 OLA P的实现通常依赖于关系型数据库管理系统(RDBMS)和相关的 OLAP 工具。这些工具可以提供从关系型数据到多维数据模型的转换功能,并支持多维分析查询。

关系型 OLAP 以关系型数据库为核心,通过关系型结构进行多维数据的表示和存储。它利用关系型数据库的查询优化和索引技术,来提高 OLAP查询的性能

使用场景:关系型 OLAP 主要适用于那些已经使用关系型数据库存储数据的场景。它可以将关系型数据库中的数据转化为多维数据模型,从而进行多维分析。适用于对查询模式不固定、查询灵活性要求高的场景。如数据分析师常用的数据分析类产品,他们往往会对数据做各种预先不能确定的分析,所以需要更高的查询灵活性

优点:关系型 OLAP 的优点在于可以利用现有的关系型数据库基础设施和查询优化技术,ROLAP 不需要进行数据预处理 ( pre-processing ),因此查询灵活,可扩展性好

缺点:由于其基于关系型数据库,可能不如多维 OLAP 那样高效地支持复杂的多维分析操作。关系型 OLAP 可能需要更多的转换和映射工作,以便将关系型数据转化为多维数据模型。当数据量较大或 query 较为复杂时,查询性能也无法像 MOLAP 那样稳定。所有计算都是即时触发 ( 没有预处理 ),因此会耗费更多的计算资源,带来潜在的重复计算

3)混合 OLAP (Hybrid OLAP)

混合 OLAP,是 MOLAPROLAP 的一种融合。它旨在平衡数据处理的灵活性和查询性能,以满足复杂的数据分析需求。当查询聚合性数据的时候,使用 MOLAP 技术;当查询明细数据时,使用 ROLA 技术。在给定使用场景的前提下,以达到查询性能的最优化。混合 OLAP的技术体系架构如下图:

使用场景:混合 OLAP适用于那些既需要高效的多维分析性能,又希望利用关系型数据库的优势的场景。它结合了多维 OLAP 和关系型OLAP 的特点,提供了更加灵活和高效的数据分析解决方案。

优点:

性能与灵活性的平衡:混合 OLAP 结合了 ROLAPMOLAP 的优势,既提供了较高的查询性能,又保持了数据的灵活性。

适应性强:混合 OLAP 能够处理不同规模和复杂度的数据集,适应不同的分析需求。

易于扩展:混合 OLAP 解决方案通常具有较好的扩展性,可以随着数据量的增长和分析需求的变化进行扩展。

缺点:混合 OLAP 的劣势恰恰在于其由于集成了 MOLAPROLAP,因此需要同时支持 MOLAPROLAP,并且本身的体系结构也非常复杂。。

三、技术选型

数据特征 分析/查询需求 推荐技术
结构化 + 多维聚合分析 实时报表、BI 查询、指标下钻 Apache Doris
非结构化/半结构化 + 全文检索 日志搜索、模糊匹配、文档查询 Elasticsearch (ES)
海量稀疏 + 高并发随机读写 用户画像、设备状态、实时更新 HBase
单表宽表 + 超高吞吐聚合 行为日志、埋点分析、离线统计 ClickHouse

2、没有 “银弹”,只有 “最佳组合”:pache Doris 的崛起确实填补了“高性能 OLAP + 低运维成本”的空白,但其本质仍是分析型数据库(OLAP),不适用于事务处理或高频点查。在真实生产架构中,应采用多引擎协同模式

  • MySQL / TiDB:承载核心交易链路(OLTP)
  • Elasticsearch:支撑全文检索、日志分析、近实时监控
  • HBase:存储超大规模稀疏数据,支持毫秒级点查
  • Doris / ClickHouse:作为统一分析层,提供交互式查询与聚合能力

1、关键能力详细对比

1)数据分析与查询性能

  • ClickHouse
    • 优势:采用列式存储、向量化计算和数据分区技术,在聚合查询(如 COUNTDISTINCTGROUP BY)场景下性能极强,单表查询速度可达秒级响应。

    • 不足:多表关联查询性能较差,不支持事务和强一致性。

  • Doris
    • 优势:支持 MPP(大规模并行处理)架构,可高效处理多表 Join 和复杂维度分析,兼容 MySQL 协议,使用门槛低。

    • 不足:大数据量下(万亿级)存储成本较高,实时导入性能略逊于 ClickHouse

  • Elasticsearch
    • 优势:全文检索和模糊查询能力突出,支持复杂的布尔查询和地理位置查询,适合非结构化数据(如日志、文档)。

    • 不足:聚合分析性能较弱,大数据量下集群维护成本高,不适合复杂的数值计算。

  • HBase
    • 优势:基于 HDFS 的分布式存储,支持海量数据随机读写,高并发场景下(如千万级 QPS)性能稳定。

    • 不足:查询接口较简单,复杂分析需结合其他工具(如 Spark),不适合实时分析。

2)数据导入与实时性

  • ClickHouse:支持批量导入(如 CSVParquet)和实时导入(Kafka),导入速度可达每秒数百万行,但实时性受分区策略影响。
  • Doris:支持实时导入(通过 BrokerStream Load),亚秒级延迟,适合实时数仓场景。
  • Elasticsearch:近实时索引(数据写入后秒级可查),但大规模写入时可能影响查询性能。
  • HBase:实时写入性能优异,支持单行实时更新,适合需要频繁修改数据的场景(如用户画像实时更新)。

3)按查询吞吐(TPS/QPS)与查询类型选型

  • 若业务以 高并发点查 为主 → 选 HBaseMySQL
  • 若需 复杂 SQL + 多维分析 → 选 Doris
  • 若为 单表宽表聚合 → 选 ClickHouse
  • 若核心是 全文检索/日志搜索 → 选 Elasticsearch
场景 Doris ClickHouse
单表聚合(10亿行) 优秀(毫秒级) 极优(业界标杆)
多表 Join(10 表) 优秀(秒级) 差(可能超时或 OOM)
实时点查(维度表) 中等(依赖 Unique Key 模型) 较好(但不如 Redis)
高并发小查询 优秀

a、mysql

  • 点查(主键或唯一索引精确查询)
    • 典型场景:SELECT * FROM users WHERE id = 12345
    • 吞吐能力:单实例可支撑 3,000~10,000 QPS
    • 响应耗时:P95 延迟 1~5 毫秒,性能极佳
    • 依赖条件:必须命中主键或唯一二级索引,且数据常驻 Buffer Pool
  • 复杂查询(多表 JOIN、子查询、非索引过滤)
    • 典型场景:多表关联用户订单 + 商品信息,带非索引字段 WHERE 条件
    • 吞吐能力:QPS 通常降至 100~500
    • 响应耗时:P95 延迟 100~1000 毫秒,易受锁竞争和回表影响
    • 局限性:缺乏列存与向量化执行,大结果集排序/分组开销高
  • 聚合与分析查询
    • 支持基础 GROUP BYCOUNTSUM,但无预聚合机制
    • 百万级数据聚合 P95 延迟约 200~800 毫秒;千万级以上显著恶化
    • 不适合 OLAP 场景,建议将聚合结果同步至 Doris 或 ClickHouse
  • 深分页表现
    • LIMIT 100000, 20 需扫描 100,020 行,QPS 降至 <50,延迟 >1 秒
    • 推荐改用书签分页(如 WHERE id > last_id)以维持毫秒级响应

b、Doris

  • 点查(分区键 + 聚合键精确过滤)
    • 典型场景:SELECT user_id, total_sales FROM sales_agg WHERE dt='2025-03-05' AND user_id='U123'
    • 吞吐能力:1,000~5,000 QPS
    • 响应耗时:P95 10~50 毫秒
    • 优势:支持 Unique Key 模型实现高效点查,类似宽表 KV
  • 复杂查询(多表 JOIN、子查询、窗口函数)
    • 典型场景:用户画像 JOIN 订单表 + 时间窗口统计
    • 吞吐能力:100~500 QPS
    • 响应耗时:P95 200 毫秒~2 秒
    • 优势:MPP 架构支持分布式 JOIN,兼容标准 SQL,BI 工具无缝对接
  • 聚合与分析查询
    • 支持预聚合模型(Aggregate Key)、物化视图、Rollup
    • 亿级数据多维 GROUP BY P95 延迟 300 毫秒~1.5 秒
    • 列存 + 向量化执行显著优于传统行存数据库
  • 深分页表现
    • 浅分页(OFFSET < 1万)性能良好;深分页需改用书签分页
    • 书签示例:WHERE (sales, user_id) < (last_sales, last_id) ORDER BY sales DESC

c、ClickHouse

  1. 点查(主键范围或精确匹配)
    • 典型场景:SELECT * FROM logs WHERE event_id = 'E999'(event_id 为 ORDER BY 前缀)
    • 吞吐能力:5,000~10,000 QPS
    • 响应耗时:P95 5~20 毫秒
    • 前提:必须命中主键索引(即表的 ORDER BY 字段前缀)
  2. 复杂查询(多表 JOIN、子查询)
    • 性能较差:JOIN 需将右表加载至内存,大表 JOIN 易 OOM
    • 吞吐能力:<100 QPS
    • 响应耗时:P95 1~10 秒,甚至超时
    • 最佳实践:避免运行时 JOIN,提前构建宽表
  3. 聚合与分析查询
    • 单表聚合(COUNT/GROUP BY/DISTINCT)性能极强
    • 亿级数据聚合 P95 延迟 20~200 毫秒
    • 支持近似计算(如 uniqCombined)进一步提速
  4. 深分页表现
    • LIMIT OFFSET 在深分页时会全量扫描,严禁使用
    • 必须采用书签分页:WHERE (ts, id) > (last_ts, last_id) ORDER BY ts, id LIMIT N

d、HBase

  1. 点查(RowKey 精确查询)
    • 典型场景:Get row 'user:12345'
    • 吞吐能力:集群级 10,000~50,000+ TPS
    • 响应耗时:P99 5~20 毫秒
    • 核心优势:海量数据下仍保持低延迟高吞吐,适合状态存储
  2. 复杂查询(非 RowKey 过滤、多条件组合)
    • 原生不支持:需通过 Filter 扫描,性能极差
    • 吞吐能力:<100 QPS
    • 响应耗时:P99 500 毫秒~数秒,随数据量线性增长
    • 实践建议:所有查询路径应在 RowKey 设计阶段固化
  3. 聚合与分析查询
    • 原生无聚合能力;Phoenix 提供有限 COUNT/SUM,但需全表 Scan
    • 响应耗时:十亿级数据聚合通常 >10 秒
    • 正确做法:通过 Spark/Flink 批处理,或同步至 Doris 做分析
  4. 深分页表现
    • Scan 支持分页,但无索引跳转,深分页效率低下
    • 仅适用于小范围滚动读取(如最近 1 万条日志)

e、Elasticsearch

  1. 点查(ID 精确查询或简单 term 过滤)
    • 典型场景:GET /logs/_doc/L999term: { "user_id": "U123" }
    • 吞吐能力:2,000~5,000 QPS
    • 响应耗时:P95 5~30 毫秒
    • 优势:倒排索引加速 term 查询,适合 ID 或标签检索
  2. 复杂查询(布尔组合、模糊匹配、脚本过滤)
    • 支持复杂 Query DSL,但脚本计算开销大
    • 吞吐能力:500~2,000 QPS(无脚本);含脚本时 <200 QPS
    • 响应耗时:P95 50~500 毫秒,脚本场景可达 1~5 秒
  3. 聚合与分析查询
    • 支持 terms、histogram、cardinality 等基础聚合
    • 十亿文档内,简单聚合 P95 延迟 100~500 毫秒,QPS 100~500
    • 多层嵌套聚合或高基数字段(如 user_id)会导致性能断崖
  4. 深分页表现
    • from/size 默认限制 from + size ≤ 10,000
    • 深分页必须用 search_after(无状态,低延迟)
    • scroll 仅用于离线导出,高并发易引发 JVM OOM

4)存储与成本

  • ClickHouse:压缩率高(列式存储优势),单节点存储成本较低,但集群扩展需要手动管理分片。
  • Doris:存储成本中等,支持自动分片和副本冗余,运维复杂度较低。
  • Elasticsearch:存储成本较高(每个文档需建立倒排索引),且集群规模扩大时节点资源消耗显著。
  • HBase:基于 HDFS 存储,成本低且可线性扩展,但需依赖 Hadoop 生态,部署复杂度高。

5)运维与生态

  • ClickHouse:运维门槛较高,需手动管理数据分片和副本,生态工具较少(主要依赖 BI 工具)。
  • Doris:兼容 MySQL 协议,运维工具完善(如 DorisManager),生态对接友好(Flink、Spark)。
  • Elasticsearch:生态成熟(KibanaLogstash),运维工具丰富,但集群调优难度大。
  • HBase:强依赖 Hadoop 生态,运维复杂度极高,需专业团队维护

3、选型建议:按场景匹配

1)如果你需要高性能数据分析与聚合

  • 首选 ClickHouse
    • 适合日志分析、用户行为分析、实时报表等场景
    • 尤其是单表大规模聚合查询(如统计每日活跃用户、订单金额分布)。
  • 次选 Doris
    • 若涉及多表关联分析(如用户画像与订单数据 Join
    • 或需要兼容 MySQL 生态(如对接现有业务系统),Doris 更合适。

2)如果你需要实时数仓与交互式查询

  • 首选 Doris:支持实时导入和多维分析,适合广告投放分析、实时业务监控等场景,可直接对接 BI 工具。
  • 次选 ClickHouse:若实时性要求不高(秒级导入),且以单表分析为主,ClickHouse 也可考虑。

3)如果你需要全文检索与模糊查询

  • 首选 Elasticsearch:适合搜索引擎、日志检索(如 ELK 栈)、文档管理等场景,尤其是非结构化数据的快速查询。
  • 次选 HBase + ES 组合:若数据量极大(万亿级),可采用 HBase 存储原始数据,ES 建立索引加速查询。

4)如果你需要海量数据存储与高并发读写

  • 首选 HBase:适合互联网用户画像、金融交易记录、物联网设备数据等场景,支持海量数据随机读写和高并发访问。
  • 次选 Doris:若同时需要分析能力,Doris 可作为 HBase 的上层分析引擎(如 Doris 外表查询 HBase 数据)。

四、亿级数据分页

场景 推荐方案 注意事项
简单单表分页 MySQL(小数据)、ClickHouse(大数据) ClickHouse 用书签分页
复杂条件分页 ES(全文搜索)、Doris(多维分析) ESsearch_after
大规模导出 ClickHouse 并行导出、Doris 按分区导出 避免单连接拉全量
深分页 ESsearch_afterClickHouse/Doris 用书签分页 不要依赖 LIMIT OFFSET 做深分页!
  • MySQL
    • 使用 LIMIT OFFSET 方式进行分页时,随着 OFFSET 值增大,查询性能显著下降
      • 因需扫描OFFSET + LIMIT 行数据(例如OFFSET 10万 LIMIT 10需扫描 100010 行)。
    • 为解决此问题,可以考虑采用基于主键或唯一有序字段的分页方式。
  • Elasticsearch
    • 默认限制from + size ≤ 1万,深分页需用scrollsearch_after
    • 但本质是通过游标避免重复扫描,但仍受限于内存和分布式架构。
  • ClickHouse
    • 深分页时 LIMIT OFFSET 会触发全量扫描(无论数据是否分区)
    • 因此必须用书签分页(如记录上一次查询的最大排序字段值),避免扫描无关数据。
  • TiDB/ Doris
    • 分布式架构可分摊扫描压力,但 LIMIT OFFSET 的原理仍为 “先扫描再丢弃”
    • OFFSET 过大时各节点仍需处理大量数据,导致性能下降。

3、 mysql 分页

1)limit n,m 传统分页

  • 原理:通过 LIMIT n, m 直接查询指定偏移量的数据。
  • 问题
    • 深分页性能瓶颈OFFSET 越大,扫描行数越多,如 LIMIT 1000000, 10 需遍历 100 万行,耗时可能超 10 秒。
    • 索引覆盖不足:若查询字段未完全命中索引,需回表读取数据,进一步降低性能。
    • 锁争用:高并发下 LIMIT OFFSET 可能导致行锁冲突,影响吞吐量。
  • 适用场景
    • 仅适用于数据量小(百万级以下)、分页深度浅的场景。
    • 对实时性要求高、查询逻辑简单的场景(如用户信息分页)。

2)mysql 主键分页

  • 原理:利用主键自增特性,通过记录上一次查询的最大 ID,下一次查询时从ID > last_id开始。
  • 优点
    • 避免 OFFSET 性能问题,查询时间稳定。
    • 实现简单,无需额外索引。
  • 限制
    • 仅适用于主键自增且连续的场景(如自增 ID)。
    • 若数据有删除,可能导致分页不连续。
  • 适用场景:数据按主键有序,且分页不要求绝对精确顺序的场景(如日志数据)。

3)mysql 书签分页

  • 原理:选择一个唯一且有序的字段(如时间戳、创建时间)作为 “书签”,通过该字段排序后记录上一次查询的最大值。

  • 示例 SQL

    -- 按创建时间分页(假设create_time有索引)
    SELECT * FROM table 
    WHERE create_time > '2025-05-28 00:00:00' 
    ORDER BY create_time LIMIT 100;
    
  • 优点

    • 支持非主键字段分页(如时间、状态等),灵活性高。
    • 索引优化后查询性能稳定。
  • 前提:分页字段需建立索引,且数据在该字段上有顺序性。

  • 适用场景:需要按时间、状态等非主键字段分页,且数据量亿级的场景(如订单数据)。

2、Elasticsearch

  • 原理:将数据同步至 ES,利用其倒排索引和分布式架构实现高效分页和搜索。
  • 优点
    • 支持复杂条件(如全文搜索、多字段过滤)的分页查询。
    • 分布式架构可处理亿级数据,性能稳定。
  • 限制
    • 深度分页(如 from > 10000)受 ES “深度分页” 限制(默认 from + size ≤ 10000),需通过 scroll search_after优化。
    • 需维护 ES 集群,增加系统复杂度。
  • 适用场景:需要复杂查询条件(如模糊搜索、多维度过滤)的分页场景(如商品搜索、日志查询)。

1)scrollsearch_after

特性 scroll search_after
适用场景 全量导出、离线批处理 实时深分页、在线翻页
  scroll 是一把锋利但危险的刀——只在必要时使用,并严格管控其生命周期。 search_after 无状态,不占服务端资源
是否快照 是(基于 _doc 快照,不受新写入影响) 否(反映最新数据)
排序要求 必须按 _doc 排序(最快) 必须指定唯一排序字段(如 timestamp, id
能否随机跳页 只能顺序遍历 只能顺序遍历(但可从任意点开始)
资源占用 高(服务端维护 scroll 上下文) 低(无状态)
过期时间 需手动设置(如 scroll=1m

2)scroll 有啥问题

a、scroll 使用快照,是不是加到内存中了?

是的,ES 会在服务端为每个 scroll 上下文维护一个“搜索快照”,这个快照会占用堆内存(heap memory)。

b、如果有很多个导出,是不是内存会溢出?

A:是的!如果同时开启大量 scroll 上下文(比如成百上千个),且每个上下文存活时间长、数据量大,极有可能导致:

  • JVM 堆内存耗尽(OOM
  • GC 压力剧增 → 节点卡顿甚至崩溃
  • 集群不稳定

c、内存消耗多大?

  • 一个 croll 上下文 ≈ KB ~ 几十 KB(取决于分片数和查询复杂度)
  • 10,000 个活跃 scroll可能占用 1~5 GB 堆内存
  • 如果每个 scroll 遍历的是 TB 级索引 → 内存压力更大
因素 影响
索引分片数 每个 shard 都要维护游标 → 分片越多,开销越大
文档总数 快照本身不存全文,但要维护 doc ID 列表(位图或迭代器)
scroll 存活时间 时间越长,内存占用越久
并发 scroll 数量 线性增长!1000 个 scroll ≈ 1000 倍内存

3、TiDB

  • 原理:支持标准 LIMIT OFFSET,但通过分布式架构将查询路由到多个节点并行处理,深分页性能比单节点 MySQL 更优,但仍受 OFFSET 影响(如 OFFSET=100万 需跨节点聚合数据,耗时较高)。

4、Doris

  • 原理:采用 MPP 架构,通过分布式查询计划将分页任务拆分为子任务,各节点并行处理后合并结果。利用分区(如时间)与分桶(如哈希)裁剪数据范围,结合聚合索引减少扫描量。
-- 按时间分区+聚合分页(假设表按dt分区,预聚合sales字段)
SELECT user_id, SUM(sales) FROM sales 
WHERE dt BETWEEN '2025-05-01' AND '2025-05-31' 
GROUP BY user_id 
ORDER BY SUM(sales) DESC 
LIMIT 50;
  • 优点:
    • MPP 并行优化:亿级数据分页查询可下推至多节点并行计算,耗时从 MySQL 的分钟级降至秒级。
    • 列存与聚合能力:支持预聚合模型(Aggregate Key),分页时直接查询聚合结果,减少数据量。
    • 兼容 SQL 语法:支持标准 LIMIT OFFSET,适配现有业务 SQL,降低改造成本。
  • 限制:
    • 深分页性能衰减OFFSET 过大时(如 10 万 +)仍需全量扫描,需结合业务限制分页深度。
    • 导出文件大小限制:单批次导出建议不超过 50GB,超大表需按分区拆分导出。
    • 实时更新成本高:频繁更新会触发数据重分布,影响分页性能。
  • 常规分页Doris 在处理亿级数据量的常规分页查询时,如果查询条件合理,能够利用索引和分区等优化手段,也可以有较好的性能表现,一般能在秒级内返回结果。
    • 例如,对于有主键或唯一键约束的表,按照主键或唯一键进行分页查询,性能较为稳定。
  • 深分页
    • Doris 没有像 ClickHouse 明确不支持深分页,但在深分页场景下性能也会受到一定影响。随着偏移量增大,性能逐渐下降。
    • 如果查询语句能够通过索引、分区等方式有效减少数据扫描范围,即使是较深的分页查询,也能在可接受的时间内返回结果。
    • 例如,在查询条件中指定了具体的分区范围或使用了索引列进行过滤,然后再进行分页,对于亿级数据量,可能在几十秒内完成深分页查询。
  • 适用场景:企业级 OLAP 分页(如多维度销售报表)、批量数据导出(如月度财务数据备份)、实时数仓场景下的交互式查询。

5、ClickHouse

  • 原理:基于列式存储与向量化计算,通过分区裁剪与并行查询实现分页。利用主键(如时间 + ID)或二级索引快速定位数据块,分布式集群将查询任务分发至各节点并行处理,最后合并结果。
-- 按时间分区+主键分页(假设表按date分区,主键为id)
SELECT * FROM orders 
WHERE date = '2025-05-29' 
ORDER BY id 
LIMIT 100 OFFSET 1000;
  • 优点:
    • 列式存储高效:仅读取查询所需列,减少 IO 开销,亿级数据分页响应可达亚秒级 (分区裁剪跳过无关数据后)。
    • 并行计算能力强:分布式架构支持千万级 QPS,复杂聚合(如 COUNT/SUM)与分页可同步完成。
    • 实时性好:数据导入后立即可查,适合实时分页场景。
  • 限制:
    • 多表关联性能差:不擅长复杂 JOIN,分页若涉及多表需提前预聚合。
    • 内存占用高:向量化计算需加载大量数据到内存,深分页可能触发 OOM
    • 高并发支持有限:单节点高并发查询易导致 CPU 饱和,需集群扩展。
    • 不支持 LIMIT OFFSET 深分页(偏移量过大会全量扫描),需用 ORDER BY + LIMIT 配合书签;
  • 常规分页:在有合适的分区键和索引,并且查询条件能够有效利用分区裁剪和索引过滤的情况下,对于亿级甚至更大规模的数据,ClickHouse 可以实现高效的常规分页查询,通常能在亚秒级或几秒内返回结果。
    • 例如,在按时间分区的表中,根据时间范围进行分页查询,每次查询最新的几万条数据,性能表现良好。
  • 深分页不支持 LIMIT OFFSET 形式的深分页,当偏移量过大时,会导致全量扫描,性能急剧下降。如果没有有效的过滤条件和索引支持,即使是千万级数据量的深分页查询,也可能会耗费很长时间,甚至导致查询失败。

  • 适用场景:单表分析型分页(如用户行为日志、实时订单统计)、大规模数据实时导出(如每日报表生成)。

ContactAuthor