

























本文将用图文结合的方式,深入探讨两种技术在数据存储、索引机制和查询性能方面的核心差异,帮助您做出更明智的技术选型。
关系型数据库(如MySQL/PostgreSQL) 和 Elasticsearch 代表了两种截然不同的数据处理哲学:
让我们通过一个直观的比喻来理解:
graph LR A[RDBMS] --> B[("图书馆模型<br/>严格有序")] C[Elasticsearch] --> D[("搜索引擎模型<br/>快速检索")]
RDBMS采用行式存储,将整行数据连续存储在磁盘上:
| ID | Name | Age | Diagnosis | Tags |
|---|---|---|---|---|
| 1 | 张三 | 25 | 感冒, 肺炎 | 发热, 咳嗽 |
| 2 | 李四 | 34 | 高血压 | 头晕, 测量异常 |
| 3 | 王五 | 28 | 糖尿病 | 多饮, 多尿 |
特点:
ES采用混合存储策略,兼具文档式和列式存储的优点:
文档存储(_source字段):
{
"patient_id": "001",
"name": "张三",
"age": 25,
"diagnosis": ["感冒", "肺炎"],
"tags": ["发热", "咳嗽", "呼吸道感染"]
}
列式存储(Doc Values):
诊断字段Doc Values:
感冒 → [文档1, 文档5, 文档8, ...]
肺炎 → [文档1, 文档3, 文档7, ...]
高血压 → [文档2, 文档4, 文档9, ...]
标签字段Doc Values:
发热 → [文档1, 文档6, 文档11, ...]
咳嗽 → [文档1, 文档3, 文档8, ...]
特点:
B+Tree是RDBMS最常用的索引结构,适合范围查询和排序:
graph TD A[根节点] --> B[内部节点] A --> C[内部节点] B --> D[叶子节点: 1-100] B --> E[叶子节点: 101-200] C --> F[叶子节点: 201-300] C --> G[叶子节点: 301-400] D --> H[数据页: 记录1] D --> I[数据页: 记录2] E --> J[...] linkStyle 4,5,6,7 stroke:#ccc,stroke-width:1px
工作流程:
优势:
ES的核心是倒排索引,但针对不同场景有深度优化:
词项(Term) 文档ID列表(Posting List)
感冒 → [1, 5, 8, 13, 25, ...]
肺炎 → [1, 3, 7, 13, 22, ...]
发热 → [1, 6, 8, 11, 13, ...]
graph TD A[倒排索引] --> B[词项字典 Term Dictionary] A --> C[文档ID列表 Posting Lists] B --> D[索引结构优化] D --> E[FST<br/>压缩词项字典] D --> F[Skip List<br/>加速链表遍历] C --> G[压缩优化] G --> H[FOR编码<br/>帧间压缩] G --> I[Roaring Bitmaps<br/>位图压缩] E --> J[内存效率] F --> K[查询速度] H --> L[存储空间] I --> M[集合运算]
关键优化技术:
让我们通过一个具体例子来说明:查询同时患有"感冒"和"肺炎"的患者
SELECT p.*
FROM patients p
JOIN patient_tags pt1 ON p.id = pt1.patient_id
JOIN tags t1 ON pt1.tag_id = t1.id AND t1.name = '感冒'
JOIN patient_tags pt2 ON p.id = pt2.patient_id
JOIN tags t2 ON pt2.tag_id = t2.id AND t2.name = '肺炎';
执行过程(涉及大量磁盘IO和JOIN操作):
graph LR A[查询解析] --> B[索引查找感冒标签] A --> C[索引查找肺炎标签] B --> D[获取感冒患者ID集合] C --> E[获取肺炎患者ID集合] D --> F[内存JOIN操作] E --> F F --> G[回表查询患者详情] G --> H[返回结果]
{
"query": {
"bool": {
"must": [
{ "term": { "tags.keyword": "感冒" } },
{ "term": { "tags.keyword": "肺炎" } }
]
}
}
}
执行过程(内存中的高效集合运算):
graph LR A[查询解析] --> B[倒排索引查找] B --> C[获取感冒Posting List] B --> D[获取肺炎Posting List] C --> E[位图AND运算] D --> E E --> F[从_source获取详情] F --> G[返回结果]
| 对比维度 | RDBMS | Elasticsearch |
|---|---|---|
| 数据定位 | 需要多次索引查找+JOIN | 直接倒排索引定位 |
| 集合运算 | 在应用层或数据库层做JOIN | CPU级别的位运算 |
| IO模式 | 随机IO较多(尤其大数据量) | 顺序读取+内存计算 |
| 缓存机制 | 缓存数据页 | 缓存过滤结果(Bitset) |
Elasticsearch通过增加存储开销来换取查询性能:
空间开销主要来自:
空间占用对比示例(100万条病历记录):
| 存储内容 | RDBMS大小 | ES大小 | 倍数 |
|---|---|---|---|
| 原始数据 | 500MB | 500MB | 1x |
| 主键索引 | 100MB | - | - |
| 倒排索引 | - | 1.5GB | 15x |
| Doc Values | - | 800MB | 8x |
| 总占用 | ~600MB | ~2.8GB | 4.7x |
ES的空间开销带来了实实在在的价值:
// 多标签组合查询:发热、咳嗽、但不包含肺炎的男性患者
{
"query": {
"bool": {
"must": [
{ "terms": { "tags": ["发热", "咳嗽"] } },
{ "term": { "gender": "男" } }
],
"must_not": [
{ "term": { "tags": "肺炎" } }
]
}
}
}
优势:毫秒级响应,即使数据量达到亿级
// 在病历描述中搜索"持续性头痛伴有恶心"
{
"query": {
"match": {
"description": "持续性头痛伴有恶心"
}
}
}
优势:分词搜索、相关性评分、模糊匹配
// 统计各年龄段患者的疾病分布
{
"size": 0,
"aggs": {
"age_groups": {
"range": {
"field": "age",
"ranges": [
{ "to": 18 }, { "from": 18, "to": 35 },
{ "from": 35, "to": 50 }, { "from": 50 }
]
},
"aggs": {
"diseases": {
"terms": { "field": "diagnosis.keyword" }
}
}
}
}
}
优势:实时多维分析,秒级响应
// 查找距离某医院5公里内的发热患者
{
"query": {
"bool": {
"must": { "term": { "tags": "发热" } },
"filter": {
"geo_distance": {
"distance": "5km",
"location": { "lat": 39.9, "lon": 116.4 }
}
}
}
}
}
-- RDBMS更适合
SELECT * FROM patients WHERE id = '12345';
原因:ES的倒排索引对高基数字段效率较低
-- 需要事务保证的操作
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
原因:ES不支持ACID事务,只有基本的一致性保证
-- 多表深度关联
SELECT p.*, d.name, t.phone
FROM patients p
JOIN departments d ON p.dept_id = d.id
JOIN doctors t ON p.doctor_id = t.id
WHERE d.specialty = '心脏病科'
AND t.title = '主任医师';
原因:ES不是为关联查询设计的,需要数据冗余或应用层处理
原因:ES的索引更新成本较高,涉及倒排索引重建
在实际生产环境中,通常采用混合架构:
graph TD A[应用系统] --> B{Router} B -->|事务操作| C[RDBMS<br/>MySQL/PostgreSQL] B -->|搜索分析| D[Elasticsearch<br/>搜索集群] C --> E[数据同步] D --> E E --> F[ETL/CDC工具<br/>Canal/Logstash] F --> D
分工明确:
通过本文的对比分析,我们可以得出以下结论:
技术选型建议:
希望这篇详细的对比能帮助您更好地理解两种技术的差异,并在实际项目中做出明智的技术决策。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。