@[toc]
引言
我是国产数据库的忠实拥趸,不久前才接触过 KingbaseES V9R1,现在 KingbaseES V9R2C13 就推出了,自然要赶紧亲手下体验一番。
假设 V9R1 打下了"稳定适配"的根基,那么 V9R2 就像是装上了"性能提升"的引擎,恰巧碰上金仓第 6 期"性能改良深度体验"活动,我打算带大家一起在 Windows 平台上运行最新的 V9R2C13(Oracle 兼容版),我们这次不只是安装一个库,还要深入底层探究其改良器在 SQL 执行机制方面做了哪些大幅改动。
下面的文章将会利用 ksql 命令行工具,一步步引导大家完成从"安装部署"到"性能调优"的整个过程。
一、 Windows 环境下极速部署 V9R2C13
💡 提个醒 :如果你是第一次安装,想要那种手把手的图形化步骤、环境变量怎么配、报错了怎么办,建议先去翻翻我之前写的那篇保姆级教程:《Windows 安装 KingbaseES V9R1C10 与 Oracle 兼容特性实战》。
这次咱们就不啰嗦基础了,重点看看 V9R2 版本有哪些不一样的地方。
1.1 搞定安装包
直接去金仓官网的下载中心,摸到 V9R2C13 的目录,把那个 Windows X86_64 的安装包 KingbaseES_V9R2_Windows_x86_64_Install.iso 下下来就行。 

1.2 安装时的关键点(Oracle 兼容模式)
跑安装程序的时候,有几个配置得盯着点,这直接关系到后面用起来兼不兼容:
-
安装集选择 :选"完全安装"或者"客户端+服务端"都行。

-
初始化数据库(这步很关键):
- 数据库模式(Mode) :一定、一定、一定要选 Oracle 兼容模式。这可是金仓的看家本领,以前用 Oracle 的老代码能不能平滑迁过来,全看这一步。
- 字符集 :没特殊情况就用
UTF8。 - 大小写敏感 :看你具体业务,习惯用 Oracle 的朋友通常都不太喜欢大小写敏感。


1.3 启动服务验证一下
装完之后,去 Windows 服务列表里把 KingbaseES V9 服务支棱起来。然后,咱们用金仓自带的 ksql 命令行工具连一下试试。
打开 CMD 或者 PowerShell,溜达到安装路径的 server\bin 底下,敲这个命令:
bash
# 默认端口为 54321,默认用户为 system,默认数据库为 test
ksql -U system -d test -h 127.0.0.1 -p 54323

二、 性能优化深度体验:看看优化器有多"聪明"
这次活动的"性能优化"清单里,最吸引我的就是 "优化器执行机制优化" 。官方文档里吹了一波 V9R2 支持 "OR 转 UNION ALL" 的自动优化,说是处理复杂查询的时候能让索引利用率蹭蹭往上涨。
光听不练假把式。咱们直接上 ksql,造它一百万条数据,看看 V9R2 的优化器是不是真像传说中那么神。
2.1 准备工作:造点测试数据
先来个模拟的"订单表",这就包含 ID、客户 ID 和 状态码,顺手塞进去 100 万条 数据。
在 ksql 里把下面这些 SQL 跑一遍:
sql
-- 1. 创建订单表
CREATE TABLE t_orders (
order_id INT PRIMARY KEY,
customer_id INT,
status_code INT,
order_date DATE
);
-- 2. 插入 100 万条模拟数据 (使用 generate_series 生成)
-- customer_id 随机范围 1-10000,status_code 随机范围 1-10
INSERT INTO t_orders
SELECT
n,
(random() * 10000)::INT,
(random() * 10)::INT,
CURRENT_DATE - (random() * 365)::INT
FROM generate_series(1, 1000000) AS n;
-- 3. 创建索引 (关键步骤!)
-- 如果没有索引,所有查询都是全表扫描,优化器就无从发挥了
CREATE INDEX idx_customer ON t_orders(customer_id);
CREATE INDEX idx_status ON t_orders(status_code);
-- 4. 收集统计信息,确保优化器拿到最新数据
ANALYZE t_orders;

2.2 深度实测:OR 查询自动重写
做开发的兄弟们肯定经常碰到这种需求:"帮我把客户ID是 888 或者 状态码是 5 的订单都捞出来"。
写成 SQL 很简单:
sql
SELECT * FROM t_orders WHERE customer_id = 888 OR status_code = 5;
🧐 传统数据库的痛点
在以前很多老版本的数据库里,用 OR 连接两个带索引的条件,优化器往往比较"轴",它要么只能选其中一个索引,要么干脆两手一摊直接全表扫描(Seq Scan),那查询效率慢得让人想砸键盘。
🚀 KingbaseES V9R2 的表现
来看看 V9R2C13 面对这道题是怎么解的。我们在 ksql 里加个 EXPLAIN 看看它的解题思路:
sql
EXPLAIN (ANALYZE, VERBOSE, BUFFERS) SELECT * FROM t_orders WHERE customer_id = 888 OR status_code = 5;
实测执行计划如下:
ini
Bitmap Heap Scan on public.t_orders (cost=1926.71..9848.70 rows=100723 width=20) (actual time=17.771..53.977 rows=100367 loops=1)
Output: order_id, customer_id, status_code, order_date
Recheck Cond: ((t_orders.customer_id = 888) OR (t_orders.status_code = 5))
Heap Blocks: exact=6411
Buffers: shared hit=6694
-> BitmapOr (cost=1926.71..1926.71 rows=100733 width=0) (actual time=15.474..15.477 rows=0 loops=1)
Buffers: shared hit=283
-> Bitmap Index Scan on idx_customer (cost=0.00..5.17 rows=100 width=0) (actual time=0.046..0.047 rows=97 loops=1)
Index Cond: (t_orders.customer_id = 888)
Buffers: shared hit=4
-> Bitmap Index Scan on idx_status (cost=0.00..1871.17 rows=100633 width=0) (actual time=15.423..15.424 rows=100282 loops=1)
Index Cond: (t_orders.status_code = 5)
Buffers: shared hit=279
Planning Time: 0.228 ms
Execution Time: 60.871 ms

执行结果深度分析:
盯着上面这张执行计划图,咱们能挖出 KingbaseES V9R2 优化器的几个"骚操作":
-
路选得很准(智能选择 BitmapOr) : 优化器眼光很毒,一眼就看出
customer_id和status_code这俩字段都有索引。它既没傻乎乎地全表扫,也没偏心地只用一个,而是祭出了 BitmapOr 大法。- 先分别对着
idx_customer和idx_status搞一波 Bitmap Index Scan(位图索引扫描)。 - 然后在内存里把这俩位图结果做个"或"运算。
- 最后,拿着结果去表里捞数据(Bitmap Heap Scan)。
- 先分别对着
-
快得飞起:
- Planning Time 只有 0.228 ms,说明优化器脑子转得极快,瞬间生成计划。
- Execution Time 才 60.871 ms。从 100 万条数据里筛出 10 万条,这速度,基本上就是眨眼即达。
-
算得很准 : 留意一下
rows=100723(估算的)和rows=100367(实际的),这俩数差得非常小。说明ANALYZE收集的情报很准,优化器做决策自然就有底气。 -
内存省着用 :
Buffers: shared hit=6694意味着所有数据都是直接从内存(Shared Buffers)中命中,完全没动用物理磁盘 I/O(Read=0)。金仓的缓存管理机制确实有一套。
结论: 这波实测下来,KingbaseES V9R2 在处理 OR 多条件查询时的"智商"确实在线。通过 BitmapOr 机制,完美解决了传统数据库在 OR 查询上索引失效的老大难问题,复杂查询也能跑出火箭速度。
🔄 进阶玩法:强制 OR 转 UNION ALL
在某些数据量大到离谱的场景下,UNION ALL 的表现可能比 BitmapOr 还要猛。V9R2 的优化器学会了自动改写 ,它会自己算笔账,如果划算,它会在后台默默地把 OR 语句变成这样:
sql
SELECT * FROM t_orders WHERE customer_id = 888
UNION ALL
SELECT * FROM t_orders WHERE status_code = 5 AND LNNVL(customer_id = 888); -- LNNVL用于去重
这招能保证每一部分查询都精准踩在索引(Index Scan)上,省去了位图操作的开销,特别是数据回表量大的时候,效果杠杠的。
2.3 性能监控实战:抓出慢 SQL
除了指望优化器自己动脑子,咱们做 DBA 或者开发的,也得有主动发现问题的能力。V9R2 提供了很全的性能视图。
在 ksql 里,想抓出系统里那些拖后腿的慢 SQL,其实很简单:
sql
-- 查看当前正在执行且耗时超过 1 秒的 SQL
SELECT
pid,
usename,
state,
query_start,
now() - query_start AS duration,
query
FROM sys_stat_activity
WHERE state != 'idle'
AND now() - query_start > interval '1 second'
ORDER BY duration DESC;
就这么一条简单的命令,配合上 V9R2 强大的 sys_stat_statements 插件,性能瓶颈在哪儿一目了然。然后再用前面说的 EXPLAIN 工具针对性地修修补补,齐活儿。
三、 结语
我这次把KingbaseES V9R2C13从安装开始一直到实战操作走了一遍流程,深深体会到国产数据库确实有所发展。
Windows下的安装体验比较顺滑,开启Oracle兼容模式之后,环境准备基本上就没有太高的门槛。
内核变得更为强劲,经由 ksql 实际操作可知,V9R2 的改良器并非只是个黑箱,其确实能够"思考",既会智能运用索引,也能自动改写 BitmapOr,UNION ALL 这样的复杂 SQL 性能问题。
对于开发者而言,最令人高兴的消息在于,以后无需再为性能而烦恼,手动将 OR 转换为 UNION ALL ,因为 KingbaseES V9R2 会在后台自动完成此项工作。
国产数据库,这就有点意思了,未来可期啊!🚀