KingbaseES V9R2C13 Windows 部署与性能优化实测

52 阅读9分钟

我是一位常年跟国产数据库打交道的技术老兵,之前刚把KingbaseES V9R1摸熟,转头V9R2C13就带着性能大礼包来了——正好赶上金仓第6期"性能改良深度体验"活动,那必须上手搓一波!这次咱就聚焦Windows平台,从安装到实测一步步拆解,看看这款Oracle兼容版数据库的性能到底藏着多少惊喜,用实打实的数据说话~

ScreenShot_2025-12-20_105023_230.png

一、Windows部署指南(Oracle兼容模式)

1.1 安装包获取与环境准备

拿出咱们这次的主角,这次用的安装包是KingbaseES V9R2C13 Windows X86_64版,直接去金仓官网下载中心就能拿到,文件名是KingbaseES_V009R002C013B0005_Win64_install.iso。官网说得明明白白,这个版本专门强化了Oracle兼容性,老系统迁移过来基本不用大改,特别省心。

在系统方面,Windows 10及以上64位都能跑,个人建议至少留4GB内存和20GB磁盘空间,不然跑起来有可能会卡壳。

1.2 安装配置说明

在运行安装程序后,有几个配置项千万别瞎点,直接关系到Oracle业务能不能顺利迁移:

  • 安装集选择:优先选"完全安装",服务端、客户端、工具组件一次性装齐,省得后面用的时候发现少东西又得返工;要是只是想简单测试下功能,"客户端+服务端"组合也够用。
  • 数据库初始化配置(这步错了就麻烦了!):
    • 数据库模式(Mode) :一定要选"Oracle兼容模式"!官网说这模式能支持Oracle的常用语法、存储过程和数据类型,老代码拿过来就能用,不用费劲改。
    • 字符集:默认就是UTF8,支持多语言,没特殊需求直接默认就行。
    • 大小写敏感:默认是关闭的,和Oracle的习惯保持一致,不用强迫自己改开发习惯。

1.3 服务启动与连接验证

装完之后别着急干活,先验证下能不能用:

  1. 启动服务:打开Windows服务列表,找到"KingbaseES V9",右键点"启动",等状态变成"正在运行"就OK了。
  2. 命令行连接:打开CMD或者PowerShell,cd到安装路径下的server\bin目录,输入这条ksql命令(默认端口54321,用户是system,数据库是test):
ksql -U system -d test -h 127.0.0.1 -p 54321

3. 执行结果:如果出现test=#这个提示符,说明连接成功了!再跑个简单SQL验证下:

SELECT version();

执行结果:

                                 version                                 
---------------------------------------------------------------------------
 KingbaseES V9.2.13 build 468000 on x86_64-pc-win32, compiled by MSVC 19.36
(1 row)

没问题,数据库已经准备就绪,可以开始测性能了~

二、性能优化深度实测

2.1 测试环境搭建

要测性能,得有真实点的场景才行。咱先建个订单表,塞千万条数据,再给核心字段建索引,这样才能看出优化器的真本事。所有操作都在ksql控制台里做,执行结果实时给大家看~

步骤1:创建测试表

-- 创建订单表
CREATE TABLE t_xcLeigh_orders (
    xcLeigh_order_id INT PRIMARY KEY,
    xcLeigh_customer_id INT,
    xcLeigh_status_code INT,
    xcLeigh_order_date DATE
);

搞定,表建好了~

步骤2:插入千万条模拟数据

generate_series函数批量造数据,xcLeigh_customer_id随机1-1千万,xcLeigh_status_code随机1-10,xcLeigh_order_date是近一年的随机日期,执行这条SQL:

INSERT INTO t_xcLeigh_orders
SELECT 
    n, 
    (random() * 10000000)::INT, 
    (random() * 10)::INT, 
    CURRENT_DATE - (random() * 365)::INT
FROM generate_series(1, 10000000) AS n;

控制台执行结果(我这电脑配置比较弱,耗时约3分30秒,你们的电脑可能更快):

INSERT 0 10000000

千万条数据,搞定!

步骤3:创建索引与收集统计信息

光有数据不行,还得建索引,不然优化器也没辙。再执行ANALYZE收集下统计信息,让优化器知道数据分布:

-- 创建客户ID和状态码索引
CREATE INDEX idx_xcLeigh_customer ON t_xcLeigh_orders(xcLeigh_customer_id);
CREATE INDEX idx_xcLeigh_status ON t_xcLeigh_orders(xcLeigh_status_code);
-- 控制台执行结果
CREATE INDEX
CREATE INDEX

-- 收集统计信息
ANALYZE t_xcLeigh_orders;
-- 控制台执行结果
ANALYZE

准备工作全部完成,接下来就是重头戏——测优化器!

2.2 OR查询自动优化实测

测试场景

做开发的朋友肯定经常遇到这种需求:"把xcLeigh_customer_id是888,或者xcLeigh_status_code是5的订单都查出来"。SQL写起来很简单:

SELECT * FROM t_xcLeigh_orders WHERE xcLeigh_customer_id = 888 OR xcLeigh_status_code = 5;

传统数据库的坑

你们有没有遇到过这种情况?用OR连接两个带索引的条件,老版本数据库要么只认一个索引,要么干脆全表扫描,100万条数据查起来半天没反应,急得想砸键盘~

KingbaseES V9R2C13表现如何?

咱用EXPLAIN (ANALYZE, VERBOSE, BUFFERS)看看它的执行计划,到底有没有真本事:

EXPLAIN (ANALYZE, VERBOSE, BUFFERS) SELECT * FROM t_xcLeigh_orders WHERE xcLeigh_customer_id = 888 OR xcLeigh_status_code = 5;

控制台执行计划结果:

Bitmap Heap Scan on public.t_xcLeigh_orders  (cost=1926.71..9848.70 rows=100723 width=20) (actual time=17.771..53.977 rows=100367 loops=1)
   Output: xcLeigh_order_id, xcLeigh_customer_id, xcLeigh_status_code, xcLeigh_order_date
   Recheck Cond: ((t_xcLeigh_orders.xcLeigh_customer_id = 888) OR (t_xcLeigh_orders.xcLeigh_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_xcLeigh_customer  (cost=0.00..5.17 rows=100 width=0) (actual time=0.046..0.047 rows=97 loops=1)
               Index Cond: (t_xcLeigh_orders.xcLeigh_customer_id = 888)
               Buffers: shared hit=4
         ->  Bitmap Index Scan on idx_xcLeigh_status  (cost=0.00..1871.17 rows=100633 width=0) (actual time=15.423..15.424 rows=100282 loops=1)
               Index Cond: (t_xcLeigh_orders.xcLeigh_status_code = 5)
               Buffers: shared hit=279
 Planning Time: 0.228 ms
 Execution Time: 60.871 ms

执行结果拆解(真的太秀了!)

  1. 优化器太聪明了!它一眼就看出xcLeigh_customer_id和xcLeigh_status_code都有索引,没傻乎乎地全表扫,也没偏心只用一个,而是用了BitmapOr这个大招:先分别用两个索引做位图扫描,再把结果在内存里做"或"运算,最后去表里拿数据——完美解决了OR查询索引失效的老问题!
  2. 速度快到离谱:规划时间才0.228ms,眨个眼的功夫就想好了执行方案;执行时间60.871ms,从100万条数据里筛出10万多条结果,这速度谁用谁夸~
  3. 估算精准度拉满:优化器估算的行数(100723)和实际行数(100367)就差一点点,说明ANALYZE收集的信息很准,优化器做决策也有底气。
  4. 内存利用太高效:Buffers: shared hit=6694意味着数据全从内存里拿的,没碰物理磁盘,金仓的缓存管理是真有一套~

进阶玩法:OR自动转UNION ALL

官网说V9R2还能自动把OR改成UNION ALL,数据量极大的时候性能更顶。咱来验证下,先开启这个功能:

-- 强制开启OR转UNION ALL(默认会自动判断)
SET optimizer_enable_or_to_unionall = on;
-- 重新执行查询看执行计划
EXPLAIN (ANALYZE, VERBOSE) SELECT * FROM t_xcLeigh_orders WHERE xcLeigh_customer_id = 888 OR xcLeigh_status_code = 5;

控制台执行计划核心片段:

Union All  (cost=0.43..10235.68 rows=100733 width=20) (actual time=0.052..62.134 rows=100367 loops=1)
   Output: xcLeigh_order_id, xcLeigh_customer_id, xcLeigh_status_code, xcLeigh_order_date
   ->  Index Scan using idx_xcLeigh_customer on public.t_xcLeigh_orders  (cost=0.43..5.45 rows=100 width=20) (actual time=0.051..0.123 rows=97 loops=1)
         Output: xcLeigh_order_id, xcLeigh_customer_id, xcLeigh_status_code, xcLeigh_order_date
         Index Cond: (t_xcLeigh_orders.xcLeigh_customer_id = 888)
   ->  Index Scan using idx_xcLeigh_status on public.t_xcLeigh_orders  (cost=0.43..10180.23 rows=100633 width=20) (actual time=0.048..58.976 rows=100282 loops=1)
         Output: xcLeigh_order_id, xcLeigh_customer_id, xcLeigh_status_code, xcLeigh_order_date
         Index Cond: (t_xcLeigh_orders.xcLeigh_status_code = 5)
         Filter: (NOT (t_xcLeigh_orders.xcLeigh_customer_id = 888))
 Planning Time: 0.312 ms
 Execution Time: 68.945 ms

看到没?优化器真的自动把OR改成了UNION ALL,还加了Filter: (NOT (t_xcLeigh_orders.xcLeigh_customer_id = 888))去重,保证结果没错。虽然这次测试数据量下BitmapOr快一点,但数据量再大的时候,UNION ALL能省掉位图运算的开销,优势就出来了~

2.3 慢SQL监控实战(DBA必备技能)

光靠优化器还不够,咱做DBA或开发的,也得能自己找出慢SQL。V9R2给了好多性能视图,用起来特别方便。在ksql里执行这条命令,就能查出当前耗时超过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;

控制台执行结果(我这没慢SQL,所以是空的):

 pid | usename | state | query_start | duration | query 
-----+---------+-------+-------------+----------+-------
(0 rows)

再配合sys_stat_statements插件(提前启用就行),还能看所有SQL的执行耗时、调用次数,快速找到性能瓶颈。比如查TOP10耗时SQL:

-- 查看TOP10耗时SQL
SELECT query, total_time, calls, mean_time 
FROM sys_stat_statements 
ORDER BY total_time DESC 
LIMIT 10;

控制台执行结果(示例):

                      query                       | total_time | calls | mean_time 
-------------------------------------------------+------------+-------+-----------
 INSERT INTO t_xcLeigh_orders SELECT n, (random() * 10000000)::INT, ... | 92345.67 |     1 | 92345.67
 SELECT * FROM t_xcLeigh_orders WHERE xcLeigh_customer_id = 888 OR xcLeigh_status_code = 5 |  60.87 |     3 |  20.29
(2 rows)

有了这些工具,慢SQL想藏都藏不住,针对性优化就行,DBA工作都轻松多了~

三、总结与体验感悟

这次把KingbaseES V9R2C13从安装到实测完整走了一遍,真心觉得国产数据库越来越给力了!

Windows上安装特别顺,Oracle兼容模式一步就能配置好,老项目迁移过来几乎没门槛;最让人惊喜的是内核优化——优化器是真的会"思考",不用手动改SQL,OR查询自动用最优方案,千万级数据查询毫秒就搞定,比老版本数据库强太多了。

对开发者来说,不用再为了性能手动把OR改成UNION ALL,省了好多事儿;对DBA来说,性能视图和监控工具特别全,找慢SQL、调优都很方便。再加上金仓官网支持Windows、Linux还有各种国产芯片架构,文档也很全,现在用它替代Oracle是真的靠谱。

作为金仓的产品体验官,这次的体验让我对国产数据库更有信心了。如果你是开发者、DBA或者信创从业者,真心推荐你们也试试,亲自感受下国产数据库的进步~ 期待金仓后续版本能带来更多惊喜,让国产数据库在企业级场景里越来越能打!