近年来,国产数据库发展迅速,YashanDB 作为新兴企业级关系型数据库,逐渐进入开发者视野。本文基于真实环境下的性能测试数据,对 YashanDB SQL Enterprise Edition Release 23.5.1.100 与 Oracle Database 19c (Version 19.3.0.0.0) 在多个典型 SQL 查询场景中的表现进行横向对比,涵盖全表扫描、聚合查询、NULL 值处理、索引跳扫、分页查询等高频业务操作。
测试环境统一部署于 VMware 虚拟机(2核 CPU / 8GB 内存),操作系统为 CentOS 7.9,测试数据源自 Oracle 的 dba_objects 表复制扩充至 1000 万行,用户权限均为 dba/connect/resource,确保公平性。所有 SQL 执行时间单位为秒。
全表扫描(Full Table Scan, FTS)
全表扫描是大数据量查询的基础操作之一。测试语句如下:
select count(1) from t1;
执行结果显示:
- Oracle 19.3:耗时
1.53 秒,Cost 为 48717(100),A-Time 显示为 00:00:01.52
- YashanDB 23.5:耗时
0.91 秒,Cost 为 541878(0),A-Time 以微秒显示为 907711
尽管 YashanDB 的 Cost 值远高于 Oracle,但实际执行时间更短,表明其在 I/O 调度或缓存机制上可能存在优化优势。此外,YashanDB 的执行计划中显示 loops: 23,fetch 行数为 23,而 Oracle 为 24 行,反映出两者在底层数据读取策略上的差异。
Max 与 Min 聚合查询
当同时查询最大值和最小值时,若目标列存在索引,不同数据库的执行路径可能产生显著差异。测试语句为:
select max(object_id), min(object_id) from t1;
结果如下:
- Oracle 19.3:耗时
1.55 秒,Cost 48733,选择全表扫描(FTS)
- YashanDB 23.5:耗时
1.661 秒,Cost 1789,选择索引快速全扫描(IFFS)
值得注意的是,YashanDB 利用了索引完成该操作,虽然总耗时略高,但 Cost 更低,说明其优化器认为索引访问代价更小。进一步观察发现,YashanDB 的执行循环次数(loops)高达 10000001,推测为 rows + 1 的实现方式,这可能与其内部迭代器设计有关。
若将上述语句改写为子查询形式:
select
(select max(object_id) from t1),
(select min(object_id) from t1)
from dual;
YashanDB 使用了两层嵌套循环(NL)实现,共执行 11 个操作步骤,而 Oracle 仅需 5 步。这种实现方式在复杂查询中可能导致性能差距放大,值得在应用层注意。
NULL 值查询性能差异
Oracle 的 B-tree 索引默认不存储纯 NULL 值,因此对索引列为 NULL 的查询通常无法走索引,必须使用全表扫描。而 YashanDB 的行为有所不同。
测试过程如下:
-- 更新一条记录的 created 字段为 NULL
update t1 set created = null where object_id = 73121;
-- 查询 NULL 值
select count(1) from t1 where created is null;
结果对比:
- Oracle 19.3:耗时
1.35 秒,执行计划为全表扫描
- YashanDB 23.5:耗时仅
0.001 秒,直接通过索引完成查询
这一结果强烈暗示 YashanDB 的索引结构支持存储 NULL 值或使用占位符标记,从而极大提升了 NULL 查询的效率。不过这也意味着在大量 NULL 值存在时,可能会增加索引的存储开销。
数据倾斜与直方图优化
在存在数据倾斜的列上建立索引并收集统计信息后,数据库优化器的选择尤为关键。测试中对某高度倾斜列执行大范围查询:
select count(created) from t1 where owner in ('SYS', 'SYSTEM', ...);
结果如下:
- Oracle 19.3:耗时
1.31 秒,物理读 172K,使用全表扫描
- YashanDB 23.5:耗时
1.646 秒,物理读 137711,仍使用索引范围扫描
YashanDB 的 Cost 计算值为 Oracle 的约 11.15 倍(543872 vs 48757),显示出更强的“索引偏好”。此外,YashanDB 倾向于自动为大多数列收集直方图,而 Oracle 仅对实际使用的列进行收集,这是两者在统计信息策略上的根本差异。
若强制 Oracle 使用索引(通过 Hint):
select /*+ index(t1 idx_owner_created) */ count(created) from t1 where owner in (...);
其耗时上升至 4.05 秒,物理读达 133K,说明在此场景下全表扫描确实更优。这也反映出 YashanDB 在此类决策上仍有优化空间。
多值 INDEX SKIP SCAN 性能优势
Index Skip Scan 允许在复合索引中跳过前导列进行查询。测试语句如下:
select count(object_name) from t1 t where object_type in ('DATABASE LINK', 'RULE');
结果差异极为明显:
- Oracle 19.3:耗时
3.14 秒,执行计划为全表扫描
- YashanDB 23.5:耗时仅
0.001 秒,成功使用 Index Skip Scan
即使返回结果集较少,YashanDB 依然能精准命中索引,展现出强大的解析能力。更进一步,当查询返回大量数据时,YashanDB 会自动切换回全表扫描,体现出智能的执行计划动态调整机制。
分页查询优化(LIMIT/OFFSET)
分页是 Web 应用中最常见的模式之一。测试语句如下:
select * from t1 order by object_id offset 10000 rows fetch next 10 rows only;
结果如下:
- Oracle 19.3:耗时
2.65 秒
- YashanDB 23.5:耗时
0.021~3.469 秒(随偏移递减)
YashanDB 在此场景表现出明显的 STOPKEY 下推优化能力,尤其在偏移量较大时性能优势更为突出。相比之下,Oracle 的执行计划未充分下推排序截断逻辑,导致整体性能偏低。
另外,在涉及 NOT NULL 条件的查询中:
select count(1) from t1 where created is not null;
Oracle 因索引不存 NULL 而选择全索引扫描,而 YashanDB 的执行计划不受 NOT NULL 影响,因其索引本身即包含完整值信息。
隐式类型转换与绑定变量问题
隐式转换常引发索引失效问题。测试中创建 char(10) 类型字段,并用 varchar2 变量查询:
var v_status varchar2(10);
exec :v_status := 'VALID';
select count(owner) from t1 where status = :v_status;
结果发现:
- Oracle 和 YashanDB 均能正常返回结果,未出现索引失效
- 但在 PL/SQL 块中使用
char 类型绑定变量时,两者均返回 0 行,原因是 'VALID' 被右补空格为 'VALID ',与原值不匹配
此外,YashanDB 当前暂不支持绑定变量窥探(Bind Peeking),这可能影响首次执行计划的准确性,建议在关键 SQL 中显式指定执行路径或使用 SQL Profile。
多线程架构与进程管理
YashanDB 采用多线程架构,主要线程包括 yasdb(主控)、buffer_pool、smon、ckpt、dbwr、worker 等。与 Oracle 的 PMON 进程类似机制不同,直接在操作系统层面使用 kill -9 终止客户端进程会导致数据库实例异常退出。
因此,不建议使用 kill 方式结束连接,应通过数据库命令进行安全断开:
alter system disconnect session 'sid,serial#' immediate;
这一点对于运维人员尤为重要,需避免因误操作引发服务中断。
总结与建议
综合各项测试,YashanDB 在以下方面展现出显著优势:
- NULL 值查询:得益于索引支持 NULL 存储,性能远超 Oracle
- Index Skip Scan:解析能力强,小结果集下性能极佳
- 分页查询:具备 STOPKEY 下推优化,适合高偏移分页场景
- 统计信息策略:自动收集直方图为多数列提供更优执行计划基础
而 Oracle 在以下方面仍具优势:
- Cost 模型成熟度:在数据倾斜场景下更准确判断全表扫描的优越性
- 绑定变量窥探:有助于首次执行即生成合理计划
- 进程稳定性:PMON 可自动清理异常会话,容错性强
对于开发者而言,可根据具体业务场景选择合适的数据库。若系统频繁涉及 NULL 查询、多值 IN 查询或深度分页,YashanDB 是极具潜力的替代方案。而对于传统 OLTP 系统、已有大量 Oracle 生态依赖的应用,则仍可优先考虑 Oracle。
如需深入学习数据库内部机制与性能调优技巧,可参考 后端 & 架构 相关资源,涵盖分布式系统、高并发设计、SQL 优化模式等内容。
参考资料
[1] YashanDB vs Oracle 性能测试, 微信公众号:mp.weixin.qq.com/s/z0kbzbCULkkL5Dk8GZ9gQA
版权声明:本文由 云栈社区 整理发布,版权归原作者所有。