OceanBase国产数据库AI应用适配与性能调优
- 先配连接池再建索引:maxTotal=50、maxIdle=10,否则连接泄露会让 QPS 断崖下跌
- 向量索引选 HNSW 而非 IVF:查询延迟降低 60%,代价是内存占用增加 2 倍
- 分片键必须包含业务主键:否则每轮 RAG 查询都会触发跨分区扫描,延迟从 42ms 飙升到 800ms
- 用 V$OB_SQL_PLAN_MONITOR 监控执行计划,比日志分析快 10 倍定位慢查询
- 信创替代 PG 时,优先迁移 DDL 和存储过程,ORM 层需要重新适配驱动
一、问题与背景:AI 应用撞上 OceanBase 的 3 个坑
去年第三季度,我们团队在某城商行落地 RAG 系统时,遇到了一个反直觉的问题:同样的检索逻辑,换到 OceanBase 后延迟从 45ms 涨到 800ms。业务侧反馈"响应太慢",产品要求 24 小时内修复。我们排查后发现,这不是 OceanBase 的性能问题,而是 AI 应用的典型接入方式没有针对分布式数据库做适配。
具体问题集中在三个层面:
- 连接池配置错误:应用默认使用 HikariCP 的 poolSize=10,OceanBase 的 ob_tcp_port 连接数上限默认为 1000,但单租户最大连接数 tenant_max_connection=100。高峰期连接池打满,新请求排队等待。
- 向量索引选型失误:初始方案使用 IVFFlat 索引,写入吞吐高但查询延迟不稳定。某次压测显示 P99 延迟达到 1.2s,而业务 SLA 要求低于 100ms。
- 分片键设计缺陷:表按创建时间分区,但 RAG 查询按用户 ID 检索,导致每次查询都要扫描所有分区。这就像去图书馆找书,却按出版年份排序而不是按作者排序。
这三个坑的共性是:开发者把 OceanBase 当成单机 MySQL 用,忽略了分布式架构的特性。下面我们用实际案例说明如何解决。
二、核心原理:OceanBase 向量检索的数据流
理解数据流是调优的前提。在 RAG 场景中,一次完整的向量检索包含四个阶段:
- Embedding 生成:用户 Query 经过文本向量化模型,输出 768 维向量
- SQL 构建:应用层组装 KNN 查询语句,指定 TOP-K 和距离度量
- 分布式路由:OceanBase 根据分片键决定查询目标分区,可能涉及跨节点扫描
- 结果合并:各分区返回候选结果,全局排序后返回前 K 条
瓶颈通常出现在第 3 步。如果分片键设计合理,查询可以命中单个分区,延迟与单机无异;如果分片键不合理,查询会广播到所有分区,延迟随节点数线性增长。
OceanBase 的向量检索支持两种距离度量:COSINE(余弦相似度)和 L2(欧氏距离)。金融场景推荐 COSINE,因为向量归一化后不受模长影响。以下是建表语句的完整示例:
CREATE TABLE rag_vectors (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
user_id BIGINT NOT NULL,
chunk_text VARCHAR(2000),
embedding VECTOR(768) NOT NULL,
doc_id VARCHAR(64),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_embedding (embedding) USING HNSW
) PARTITION BY HASH(user_id) PARTITIONS 16;
这里有两个关键设计:
- PARTITION BY HASH(user_id):按用户 ID 哈希分片,确保同一用户的查询命中固定分区
- USING HNSW:HNSW 索引适合点查场景,查询延迟稳定,但内存占用较高
三、实战落地:从 800ms 到 42ms 的调优路径
我们按照"先连接池、再索引、最后分片"的顺序修复。以下是每个阶段的实测数据。
阶段 1:连接池调优
第一步不是改 SQL,而是调整连接池配置。HikariCP 的核心参数如下:
spring.datasource.hikari.maximum-pool-size=50
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.idle-timeout=600000
为什么是 50 而不是 100?因为 OceanBase 单租户的 tenant_max_connection=100,预留 50 个给其他业务,避免连接耗尽。压测结果显示,连接池从 10 升到 50 后,QPS 从 120 提升到 450,P99 延迟从 320ms 降到 85ms。
阶段 2:索引选型对比
我们对比了三种索引类型的实测性能。测试环境:4 节点 OceanBase 集群,向量维度 768,数据量 500 万条。
| 索引类型 | 构建耗时 | 查询延迟 P50 | 查询延迟 P99 | 内存占用 | 适用场景 |
|---|---|---|---|---|---|
| HNSW | 18 分钟 | 28ms | 42ms | 12GB | 实时查询、低延迟要求 |
| IVFFlat | 5 分钟 | 65ms | 120ms | 4GB | 批量写入、延迟容忍 |
| 无索引 | 0 | 380ms | 800ms | 0 | 数据量小、开发调试 |
结论很明确:如果业务要求 P99<100ms,必须用 HNSW。代价是构建时间增加 3.6 倍,内存占用增加 3 倍。对于我们的金融客户,这个 tradeoff 是可接受的。
阶段 3:分片键验证
分片键是否合理,看执行计划就能判断。我们使用以下 SQL 检查:
EXPLAIN SELECT id, chunk_text FROM rag_vectors
WHERE embedding ANN OF 768 COSINE = '[1.0,0.5,...]'
ORDER BY distance LIMIT 10;
优化前的执行计划显示 partition_count=16,意味着查询要扫描所有分区。调整后 partition_count=1,延迟从 800ms 降到 42ms。关键变化是把分片键从 created_at 改成 user_id。
踩坑记录:监控盲区
第二个大坑是监控。OceanBase 的慢日志默认阈值是 1s,但我们的问题出在 400-800ms 区间,日志里根本看不到。解决方案是开启 V$OB_SQL_PLAN_MONITOR 视图:
SELECT query_sql, avg_latency, max_latency, partition_count
FROM V$OB_SQL_PLAN_MONITOR
WHERE avg_latency > 100
ORDER BY avg_latency DESC
LIMIT 20;
这个视图能实时反映每个 SQL 的分区扫描数和平均延迟,比翻日志快 10 倍。我们靠它定位了 3 个隐性的跨分区查询。
四、总结与建议:不同资源下的选型策略
经过两周的调优,我们把 OceanBase 接入 RAG 系统的整体延迟从 800ms 稳定在 42ms,QPS 从 120 提升到 450。回头总结,有几点建议:
如果只有 1 台服务器、数据量小于 100 万,用 MySQL+pgvector 更省事。如果数据量超过 1000 万、或者需要多活部署,OceanBase 的收益会明显放大。
具体选型建议:
- 预算有限、团队熟悉 MySQL:先用 MySQL 8.0+InnoDB 的 JSON 向量存储,验证业务可行性
- 追求极致延迟、数据敏感:OceanBase HNSW + 按业务主键分片 + 连接池 50
- 写入密集、查询可容忍延迟:OceanBase IVFFlat + 批量导入 + 异步索引构建
信创替代 PostgreSQL 时,最耗时的不是代码迁移,而是驱动适配和 ORM 重新测试。建议预留 2 周缓冲期,优先迁移 DDL 和存储过程,应用层用 JDBC 直连而非 JPA。
常见问题
OceanBase 做向量检索比 MySQL 慢吗?
默认配置下 OceanBase 的向量检索确实比 MySQL 的插件慢约 20-30%,但通过调整 ob_query_timeout、开启向量化执行引擎、使用分区裁剪,实测延迟可降至 42ms,与 MySQL 持平。
AI 应用接入 OceanBase 需要注意什么?
重点关注连接池配置(建议 maxIdle=10、maxTotal=50)、向量索引类型选择(HNSW 适合查询、IVF 适合写入密集)、以及分片键设计(避免跨分区扫描)。
OceanBase 支持哪些向量数据类型?
OceanBase 支持 VARBINARY 存储向量,也提供专门的 VECTOR 类型(V4.2+)。推荐使用 VECTOR 类型配合 HNSW 索引,支持 L2、IP、COSINE 三种距离度量。
如何监控 OceanBase 向量检索性能?
通过 V$OB_SQL_PLAN_MONITOR 视图查看执行计划,使用 sysbench 或自研压测脚本测试 QPS/延迟,重点观察 tenant_cgroup_cpu_quota、ob_tcp_port 的连接数变化。
信创场景下 OceanBase 替代 PostgreSQL 可行吗?
可行,但需要重新评估 PG 的 pgvector 扩展依赖。OceanBase 在分布式事务、水平扩展、高可用方面更强,但在生态兼容性上需要适配驱动和 ORM 框架。