大数据存储中间件
前言
Github:https://github.com/HealerJean
一、数据库
1、关系型数据库
1)什么是(SQL)关系型数据库:
关系型数据库指的是使用关系模型(二维表格模型)来组织数据的数据库, 关系模型可以简单理解为二维表格模型,而一个关系型数据库就是由二维表及其之间的关系(如主键和外键)进行连接。
常见的有:
Oracle,MySql,Microsoft SQL Server,SQLite,PostgreSQL
2)优势
1、数据结构清晰,易于理解和维护。
2、 数据一致性和完整性高,通过 ACID 事务保证数据的一致性;
3、支持复杂查询,通过 SQL 语言可以方便地进行多表联合查询;
3)不足
随着互联网企业的不断发展,数据日益增多,因此关系型数据库面对海量的数据会存在很多的不足。
1、数据读写性能有限,特别是在处理大规模高并发数据时。。
2、扩展性相对较差,不易应对快速变化的数据模型。
3、 固定的数据结构可能导致灵活性不足,关系型数据库的数据模型定义严格,无法快速容纳新的数据类型(需要提前知道需要存储什么样类型的数据)
4)代表
Oracle:大型关系数据库管理系统,提供企业级的数据管理解决方案。
MySQL:开源的关系型数据库,广泛应用于各种Web应用中。
SQL Server:微软开发的关系数据库管理系统,提供丰富的功能和强大的性能。
2、非关系型数据库
1)什么是(NOSQL)非关系型数据库:
非关系型数据库(
NoSQL)泛指非关系型的、分布式的、且一般不保证遵循ACID特性的数据存储系统。它不基于关系模型,而是基于键值对、文档、图形或列式存储等方式。非关系型数据库又被称为
NoSQL(NotOnlySQL),意为不仅仅是SQL。通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定,常用于存储非结构化的数据。非关系型数据库存储数据的格式可以是
key-value形式、文档形式、图片形式等。使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
2)优势
1、 高并发读写性能,适用于大规模数据处理。
2、 海量数据的维护和处理非常轻松,成本低。
3、数据结构灵活,无需预定义表结构。
4、水平扩展性好,易于构建分布式系统。
3)不足
1、不同的非关系型数据库之间差异较大,选择时需要考虑具体需求。
1、非关系数据库没有事务处理,无法保证数据的完整性和安全性。适合处理海量数据,但是不一定安全。
3、缺乏统一的查询语言,查询和处理的复杂度可能增加。
4)代表
1、键值数据库-Redis:内存数据结构存储,可以用作数据库、缓存和消息中间件
2、列族数据库-**HBase **基于列存储的分布式数据库,适用于大规模的结构化数据存储
3、文档数据库- MongoDB 基于文档的 NoSQL 数据库,支持动态模式,适用于快速变化的数据模型
4、 图形数据库:Neo4j、InfoGrid
二、OLTP、OLAP
OLTP·(联机事务处理)应用的场景,其存储的主要是与业务直接相关的数据,强调准确、低时延、高并发,如果没有特别强调,基本上数据库里只会去存储与业务相关的数据。
OLAP(联机分析处理)是数据仓库系统的主要应用,其支持的对象只要是面向分析场景的应用,提供结构化的、主题化的数据提供给运营,做业务反馈和辅助决策用,同时,有些场景下,也可以由数据仓库对业务进行支持。
| OLTP (联机事务处理) | OLAP(联机分析处理) | |
|---|---|---|
| 使用场景 | 在线业务服务 | 数据分析、挖掘、机器学习 |
| 涉及数据量 | 当前正在发生的业务数据 | 历史存档数据 |
| 事务和数据完整性 | 对事务和数据一致性要求高 | 对实物能力没有要求,数据不一致也可以重建 |
| 功能使用需求 | 简单增删改查,要求响应时间极短 | 复杂的聚合和多数据源关联,查询时间可到分钟,小时,天 |
| 并发要求 | 高并发 | 低并发 |
| 实现方案 | 事务、索引、存储计算耦合 | 大量 SCAN、列式存储,存储计算可以分离 |
| 可用性要求 | 非常高 | 不高 |
| 技术典范 | MYSQL |
Clickhouse |
| 数据结构 | 关系数据库。 | 使用多维(多维数据集)或关系数据库。 |
1、理解篇
1)场景
场景:跟开发沟通需求时,可能会听到“这个(数据)数据库没存,取不到……”、“我这边没这张表,去找业务的人要……”、“这个(数据)在日志里,要的话提个需求给我……”、“我们两边存储的逻辑不一样,数据结果当然不一样啊”、如果你也碰到过这种情况,这节内容对你有用。这节内容将围绕数据从产生-入库-分析环节,数据库和数据仓库的区别和作用。
产品的使用者在前端做交互会产生各种行为数据,略作区分的话,可以分为行为数据,和业务数据。
⬤ 行为数据是指用户的点击、浏览等操作数据;
⬤ 业务数据本质上也是行为数据,能被叫作业务数据,是因为与产品的业务目标挂钩。如用户的注册行为、订单行为(也是需要与服务端做交互产生的数据)。
为了保证对业务的快速响应和支持,针对产品和业务功能有一个直接的数据库与之进行交互,OLTP是与功能、业务强相关的事务查询系统,要保证高并发场景下低时延的查询和处理效率,因此对 CPU 的性能要求较高。而直接存储与功能和业务直接相关的地方,就叫数据库,一般是服务端开发的同事来负责。
数据库主要为在线业务服务。如果是分析场景需要查询数据,涉及到从业务数据库取数据,就意味着会影响业务数据库对业务的支持。量小还好,量大或者查询比较复杂,服务端的同事就会担心影响到线上业务,或者把业务数据库查“崩”了影响线上业务,因此非常 nice地拒绝你的需求。
企业在经过初期的市场验证阶段后,会开始寻求从数据中找到下一步发展的方向,直接从业务数据库获取数据限制颇多,因此这时候就需要搭建数据仓库体系了。
数据仓库是独立于业务数据库之外的一套数据存储体系,OLAP 是数据仓库系统的主要应用,能够支持复杂的分析操作,与数据库需要直接直接线上业务不同,数据仓库侧重于分析决策,提供直观的数据查询结果。(当然数据仓库也是可以支持线上业务的,比如电商场景下常见的,根据用户行为做商品推荐。用户的行为数据存进数仓后,进行实时计算,然后将算法模型计算出的推荐结果发给业务端做展示。)。
在企业初期阶段,全部数据存储、业务应用支持和分析支持都是交给业务数据库来做。相比于对分析应用的支持,数据库肯定会先确保对前端业务的支持。因此在响应分析场景的需求时,速率和数据完整度往往不尽如人意。
2)过程
Q1、这个(数据)数据库没存,取不到……:
答:如果行为数据没有与业务直接关联,而且产品经理也没有要求记录,开发们大概率是不会做对应的数据采集的,所以有了上面回答。这时候要拿小本本记一下,告诉开发gg:“谢谢gg,下次我就提这个数据的采集需求!”
Q2. “我这边没这张表,去找业务的人要……”:
答:如果你们已经有了数据仓库,和 BI 应用的话,开发那边大概率会拆分一组叫【大数据】的人,他们主要负责数据仓库的建设和 B I数据产品的支持。但有的数据存在了业务数据库,没有同步到数据仓库时,你去问大数据同事要数据的时候,他们就会这样温柔地回应你。
Q3. “这个(数据)在日志里,要的话提个需求给我……”:
答:只要用户与服务端有交互(如发起了订单、注册成功等行为),业务数据库基本会将其全部记录下来,是一条条的明细数据。所以如果你提的需求恰好有,在日志里,他们需要从日志里“捞”出对应的数据,然后清洗计算之后,才能把数据拿出来,因此需要你提一个需求,要不然主管又要问他今天干啥了。
注:需注意,明细日志一般不会永久保留,过一段时间后,已经没有依赖这些数据的应用时,这些数据就会被删掉,保留时长不同公司不一样,所以上述场景发生在数据还在的前提下。
2、OLAP
OnLineAnalyticalProcessing:联机分析处理
olap是传统的关系型数据库的主要应用,主要基本的、日常的事务处理,例如银行交易。目前市面上主流的开源olap数据库引擎包含:Hive、Hawq、Presto、Kylin、Impala、Sparksql、Druid、Clickhouse、Greeplum等。
1)多维 MOLAP ( Multi-dimensional OLAP )
多维
OLAP基于直接支持多维数据和操作的本机逻辑模型。数据物理上存储在多维数组中, 并且使用定位技术来访问它们。。这种方式可以快速地响应用户的多维分析请求,提供高效的查询和分析性能,
MOLAP一般会根据用户定义的数据维度、度量(也可以叫指标)在数据写入时生成预聚合数据;Query查询到来时,实际上查询的是预聚合的数据而不是原始明细数据,在查询模式相对固定的场景中,这种优化提速很明显。
MOLAP的优点和缺点都来自于其数据预处理 (pre-processing) 环节。数据预处理,将原始数据按照指定的计算规则预先做聚合计算,这样避免了查询过程中出现大量的即使计算,提升了查询性能。但是这样的预聚合处理,需要预先定义维度,会限制后期数据查询的灵活性;
如果查询工作涉及新的指标,需要重新增加预处理流程,损失了灵活度,存储成本也很高。同时,这种方式不支持明细数据的查询,仅适用于聚合型查询(如:sum,avg,count)。
使用场景:多维 OLAP 主要适用于需要对数据进行多维分析的场景,如市场分析、销售分析等。在这些场景中,用户可以通过多维度的视角,深入剖析数据,挖掘潜在的业务价值。
优点: 多维 OLAP 的优点在于其查询和分析性能高,可以支持复杂的多维分析操作。
缺点:由于数据存储在多维数组中,可能会占用较多的存储空间。此外,对于非预定义的多维分析需求,可能需要重新构建多维数组,增加了操作的复杂性。
代表:主要有 Druid 和 Kylin 。这些系统都是基于直接支持多维数据和操作的本机逻辑模型,它们在数据写入时生成预聚合数据,从而在查询时提高查询速度,尤其在查询模式相对固定的场景中,这种优化提速效果尤为明显。
2)关系型 OLAP (Relational OLAP)
关系型
OLAP的实现通常依赖于关系型数据库管理系统(RDBMS)和相关的OLAP工具。这些工具可以提供从关系型数据到多维数据模型的转换功能,并支持多维分析查询。关系型
OLAP以关系型数据库为核心,通过关系型结构进行多维数据的表示和存储。它利用关系型数据库的查询优化和索引技术,来提高OLAP查询的性能
使用场景:关系型 OLAP 主要适用于那些已经使用关系型数据库存储数据的场景。它可以将关系型数据库中的数据转化为多维数据模型,从而进行多维分析。适用于对查询模式不固定、查询灵活性要求高的场景。如数据分析师常用的数据分析类产品,他们往往会对数据做各种预先不能确定的分析,所以需要更高的查询灵活性
优点:关系型 OLAP 的优点在于可以利用现有的关系型数据库基础设施和查询优化技术,ROLAP 不需要进行数据预处理 ( pre-processing ),因此查询灵活,可扩展性好
缺点:由于其基于关系型数据库,可能不如多维 OLAP 那样高效地支持复杂的多维分析操作。关系型 OLAP 可能需要更多的转换和映射工作,以便将关系型数据转化为多维数据模型。当数据量较大或 query 较为复杂时,查询性能也无法像 MOLAP 那样稳定。所有计算都是即时触发 ( 没有预处理 ),因此会耗费更多的计算资源,带来潜在的重复计算
3)混合 OLAP (Hybrid OLAP)
混合
OLAP,是MOLAP和ROLAP的一种融合。它旨在平衡数据处理的灵活性和查询性能,以满足复杂的数据分析需求。当查询聚合性数据的时候,使用MOLAP技术;当查询明细数据时,使用ROLA技术。在给定使用场景的前提下,以达到查询性能的最优化。混合OLAP的技术体系架构如下图:
使用场景:混合 OLAP适用于那些既需要高效的多维分析性能,又希望利用关系型数据库的优势的场景。它结合了多维 OLAP 和关系型OLAP 的特点,提供了更加灵活和高效的数据分析解决方案。
优点:
⬤ 性能与灵活性的平衡:混合 OLAP 结合了 ROLAP 和 MOLAP 的优势,既提供了较高的查询性能,又保持了数据的灵活性。
⬤ 适应性强:混合 OLAP 能够处理不同规模和复杂度的数据集,适应不同的分析需求。
⬤ 易于扩展:混合 OLAP 解决方案通常具有较好的扩展性,可以随着数据量的增长和分析需求的变化进行扩展。
缺点:混合 OLAP 的劣势恰恰在于其由于集成了 MOLAP 和 ROLAP,因此需要同时支持 MOLAP 和 ROLAP,并且本身的体系结构也非常复杂。。
三、技术选型
| 数据特征 | 分析/查询需求 | 推荐技术 |
|---|---|---|
| 结构化 + 多维聚合分析 | 实时报表、BI 查询、指标下钻 | Apache Doris |
| 非结构化/半结构化 + 全文检索 | 日志搜索、模糊匹配、文档查询 | Elasticsearch (ES) |
| 海量稀疏 + 高并发随机读写 | 用户画像、设备状态、实时更新 | HBase |
| 单表宽表 + 超高吞吐聚合 | 行为日志、埋点分析、离线统计 | ClickHouse |
2、没有 “银弹”,只有 “最佳组合”:pache Doris 的崛起确实填补了“高性能 OLAP + 低运维成本”的空白,但其本质仍是分析型数据库(OLAP),不适用于事务处理或高频点查。在真实生产架构中,应采用多引擎协同模式
MySQL / TiDB:承载核心交易链路(OLTP)Elasticsearch:支撑全文检索、日志分析、近实时监控HBase:存储超大规模稀疏数据,支持毫秒级点查Doris / ClickHouse:作为统一分析层,提供交互式查询与聚合能力
1、关键能力详细对比
1)数据分析与查询性能
ClickHouse-
优势:采用列式存储、向量化计算和数据分区技术,在聚合查询(如
COUNT、DISTINCT、GROUP BY)场景下性能极强,单表查询速度可达秒级响应。 -
不足:多表关联查询性能较差,不支持事务和强一致性。
-
Doris-
优势:支持
MPP(大规模并行处理)架构,可高效处理多表Join和复杂维度分析,兼容MySQL协议,使用门槛低。 -
不足:大数据量下(万亿级)存储成本较高,实时导入性能略逊于
ClickHouse。
-
Elasticsearch-
优势:全文检索和模糊查询能力突出,支持复杂的布尔查询和地理位置查询,适合非结构化数据(如日志、文档)。
-
不足:聚合分析性能较弱,大数据量下集群维护成本高,不适合复杂的数值计算。
-
HBase-
优势:基于
HDFS的分布式存储,支持海量数据随机读写,高并发场景下(如千万级QPS)性能稳定。 -
不足:查询接口较简单,复杂分析需结合其他工具(如
Spark),不适合实时分析。
-
2)数据导入与实时性
ClickHouse:支持批量导入(如CSV、Parquet)和实时导入(Kafka),导入速度可达每秒数百万行,但实时性受分区策略影响。Doris:支持实时导入(通过Broker或StreamLoad),亚秒级延迟,适合实时数仓场景。Elasticsearch:近实时索引(数据写入后秒级可查),但大规模写入时可能影响查询性能。HBase:实时写入性能优异,支持单行实时更新,适合需要频繁修改数据的场景(如用户画像实时更新)。
3)按查询吞吐(TPS/QPS)与查询类型选型
- 若业务以 高并发点查 为主 → 选 HBase 或 MySQL
- 若需 复杂 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 BY、COUNT、SUM,但无预聚合机制 - 百万级数据聚合 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 毫秒
- 优势:支持
UniqueKey模型实现高效点查,类似宽表KV
- 典型场景:
- 复杂查询(多表 JOIN、子查询、窗口函数)
- 典型场景:用户画像 JOIN 订单表 + 时间窗口统计
- 吞吐能力:100~500 QPS
- 响应耗时:
P95200 毫秒~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
- 点查(主键范围或精确匹配)
- 典型场景:
SELECT * FROM logs WHERE event_id = 'E999'(event_id 为 ORDER BY 前缀) - 吞吐能力:5,000~10,000 QPS
- 响应耗时:P95 5~20 毫秒
- 前提:必须命中主键索引(即表的
ORDER BY字段前缀)
- 典型场景:
- 复杂查询(多表 JOIN、子查询)
- 性能较差:JOIN 需将右表加载至内存,大表 JOIN 易 OOM
- 吞吐能力:<100 QPS
- 响应耗时:P95 1~10 秒,甚至超时
- 最佳实践:避免运行时 JOIN,提前构建宽表
- 聚合与分析查询
- 单表聚合(COUNT/GROUP BY/DISTINCT)性能极强
- 亿级数据聚合 P95 延迟 20~200 毫秒
- 支持近似计算(如 uniqCombined)进一步提速
- 深分页表现
LIMIT OFFSET在深分页时会全量扫描,严禁使用- 必须采用书签分页:
WHERE (ts, id) > (last_ts, last_id) ORDER BY ts, id LIMIT N
d、HBase
- 点查(RowKey 精确查询)
- 典型场景:
Get row 'user:12345' - 吞吐能力:集群级 10,000~50,000+ TPS
- 响应耗时:P99 5~20 毫秒
- 核心优势:海量数据下仍保持低延迟高吞吐,适合状态存储
- 典型场景:
- 复杂查询(非 RowKey 过滤、多条件组合)
- 原生不支持:需通过 Filter 扫描,性能极差
- 吞吐能力:<100 QPS
- 响应耗时:P99 500 毫秒~数秒,随数据量线性增长
- 实践建议:所有查询路径应在 RowKey 设计阶段固化
- 聚合与分析查询
- 原生无聚合能力;Phoenix 提供有限 COUNT/SUM,但需全表 Scan
- 响应耗时:十亿级数据聚合通常 >10 秒
- 正确做法:通过 Spark/Flink 批处理,或同步至 Doris 做分析
- 深分页表现
- Scan 支持分页,但无索引跳转,深分页效率低下
- 仅适用于小范围滚动读取(如最近 1 万条日志)
e、Elasticsearch
- 点查(
ID精确查询或简单 term 过滤)- 典型场景:
GET /logs/_doc/L999或term: { "user_id": "U123" } - 吞吐能力:2,000~5,000 QPS
- 响应耗时:P95 5~30 毫秒
- 优势:倒排索引加速 term 查询,适合 ID 或标签检索
- 典型场景:
- 复杂查询(布尔组合、模糊匹配、脚本过滤)
- 支持复杂 Query DSL,但脚本计算开销大
- 吞吐能力:500~2,000 QPS(无脚本);含脚本时 <200 QPS
- 响应耗时:P95 50~500 毫秒,脚本场景可达 1~5 秒
- 聚合与分析查询
- 支持 terms、histogram、cardinality 等基础聚合
- 十亿文档内,简单聚合 P95 延迟 100~500 毫秒,QPS 100~500
- 多层嵌套聚合或高基数字段(如 user_id)会导致性能断崖
- 深分页表现
from/size默认限制 from + size ≤ 10,000- 深分页必须用
search_after(无状态,低延迟) scroll仅用于离线导出,高并发易引发JVMOOM
4)存储与成本
ClickHouse:压缩率高(列式存储优势),单节点存储成本较低,但集群扩展需要手动管理分片。Doris:存储成本中等,支持自动分片和副本冗余,运维复杂度较低。Elasticsearch:存储成本较高(每个文档需建立倒排索引),且集群规模扩大时节点资源消耗显著。HBase:基于HDFS存储,成本低且可线性扩展,但需依赖Hadoop生态,部署复杂度高。
5)运维与生态
ClickHouse:运维门槛较高,需手动管理数据分片和副本,生态工具较少(主要依赖 BI 工具)。Doris:兼容MySQL协议,运维工具完善(如DorisManager),生态对接友好(Flink、Spark)。Elasticsearch:生态成熟(Kibana、Logstash),运维工具丰富,但集群调优难度大。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(多维分析) |
ES 用 search_after |
| 大规模导出 | ClickHouse 并行导出、Doris 按分区导出 |
避免单连接拉全量 |
| 深分页 | ES 用 search_after,ClickHouse/Doris 用书签分页 |
不要依赖 LIMIT OFFSET 做深分页! |
MySQL:- 使用
LIMIT OFFSET方式进行分页时,随着OFFSET值增大,查询性能显著下降- 因需扫描
OFFSET + LIMIT行数据(例如OFFSET 10万 LIMIT 10需扫描 100010 行)。
- 因需扫描
- 为解决此问题,可以考虑采用基于主键或唯一有序字段的分页方式。
- 使用
Elasticsearch:- 默认限制
from + size ≤ 1万,深分页需用scroll或search_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)scroll 和 search_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可以实现高效的常规分页查询,通常能在亚秒级或几秒内返回结果。- 例如,在按时间分区的表中,根据时间范围进行分页查询,每次查询最新的几万条数据,性能表现良好。
-
深分页:不支持
LIMITOFFSET形式的深分页,当偏移量过大时,会导致全量扫描,性能急剧下降。如果没有有效的过滤条件和索引支持,即使是千万级数据量的深分页查询,也可能会耗费很长时间,甚至导致查询失败。 - 适用场景:单表分析型分页(如用户行为日志、实时订单统计)、大规模数据实时导出(如每日报表生成)。


