一、实验背景
基于 PostgreSQL 构建日志表,通过千万级数据验证:
-
全表查询性能
-
索引(尤其 BRIN)在大数据场景的作用
二、核心结论
1️⃣ GROUP BY 不依赖索引
SELECT api, count(*) FROM logs GROUP BY api;
👉 执行计划:
-
Parallel Seq Scan
-
Hash Aggregate
结论:
❗需要扫描全部数据 → 索引无效
2️⃣ WHERE 条件 ≠ 性能提升
WHERE ts > now() - interval '1 day'
如果没有索引:
❗仍然是全表扫描 → 性能几乎不变
3️⃣ BRIN 索引的前提
CREATE INDEX ... USING BRIN(ts);
必须满足:
❗数据在物理存储上"有序"(如时间递增)
4️⃣ BRIN 的本质
不是精确查找,而是:
❗跳过不相关的数据块(减少 IO)
三、关键实验现象
❌ 无序数据(随机时间)
Parallel Seq Scan
Execution Time: ~2500ms
✅ 有序数据 + BRIN
Bitmap Index Scan
Execution Time: ~0.09ms
🎯 性能提升
❗约 1000~4000 倍
四、重要反直觉结论
❗索引不是总能加速
当查询命中数据较多(如 >20%):
-
使用索引(BRIN) → 反而更慢
-
全表扫描(Seq Scan) → 更快
五、本质理解
PostgreSQL 优化核心:
❗不是"用不用索引"
❗而是"扫描多少数据"
性能公式(核心)
查询性能 ≈ 扫描数据量(IO) + 访问方式
六、最终总结
❗MySQL 优化的是:快速定位数据(OLTP)
❗PostgreSQL 优化的是:高效处理数据(OLAP)
❗真正的优化不是"加索引"
❗而是:
减少扫描的数据量