很多做数据库选型的朋友,最近都在问我一个问题:YashanDB 到底在实际业务里好不好用?光看官网的架构图和性能报告,总觉得隔着一层。正好前阵子我用 YashanDB 完整跑过几个不同类型的业务场景,从传统 OLTP 到半结构化的 JSON 处理都摸了一遍,今天不聊虚的,直接用 5 个能落地复现的示例,把 YashanDB 在实践里的真实表现拆开讲清楚。无论你是在做国产数据库选型调研,还是已经在测试环境里折腾 YashanDB,这篇文章都能给你一些一手的参考。
这 5 个示例覆盖了关系型事务处理、复杂分析查询、JSON 半结构化数据、地理空间检索和运维管理这几个最常被问到的方向。每个示例我都会给出完整的建表语句、数据样例和核心 SQL,并交代清楚我为什么这么设计,以及实操中踩过的坑。文章偏实战,适合数据库管理员、后端开发和对国产数据库感兴趣的朋友,照着抄作业基本可行。
1. 为什么用这 5 个示例来展示 YashanDB
选这 5 个示例不是随便凑数,而是围绕 YashanDB 的几个核心能力点去设计的。YashanDB 作为一款架构上比较新的国产数据库,对外宣传的卖点集中在兼容性、高可用和混合负载处理能力上。纸上谈兵没有意义,所以我把每个示例都对应到一个真实的业务痛点,让技术在场景里自己说话。
先说说我对 YashanDB 的整体判断。它在设计上有几个让我印象深刻的点:一是语法层面对主流数据库的兼容做得比较细,MySQL 和 Oracle 的常用写法都能平滑迁移;二是存储引擎支持行存和列存,可以在同一套系统里处理交易和分析两类负载;三是在高可用层面做了共享集群的方案,不像传统主备那样存在切换窗口。这些特性在后面的示例里都会有所体现。
示例的选择也照顾到了不同视角的读者。搞业务开发的,可以重点关注事务处理和 JSON 场景;做数据分析和报表的,重点看窗口函数和复杂聚合的写法;负责运维和架构的,则可以在线索引维护和系统视图这些操作里找感觉。我把每个示例的复杂度控制在"能看懂、能复现、能举一反三"这个水平线上,太复杂反而会掩盖核心思路。
1.1 示例场景背后的业务逻辑
每个示例我都设定了一个具体的业务背景,这样 SQL 看起来才不空洞。订单事务对应电商交易,销售分析对应零售连锁,JSON 对应物联网设备上报,空间检索对应门店选址,运维示例对应大促前的系统健康检查。这些场景在现实中的出现频率很高,参考价值自然也就更高。
从技术覆盖上看,列存分区表的物化视图因为内容较长,我会拆到第三个示例里单独讲,JSON 索引和空间索引的部分则在对应示例中详细展开。你可以把这篇文章理解成一份 YashanDB 的实践索引,每个示例都是一个独立的技术切片,组合起来就构成了对 YashanDB 相对完整的认知拼图。
2. 示例一:订单系统里的 ACID 事务与主键生成策略
第一个示例回到最根本的关系型事务场景。我模拟了一个简化的订单管理系统,包含用户表、商品表、订单表和订单明细表。这个场景的难点不在于 SQL 多复杂,而在于如何保证下单过程中的数据一致性,以及在主键生成上做出合理选择。
先看建表语句。商品表里我刻意加入了库存字段,订单表使用自增主键,明细表通过外键关联订单头。这样设计是为了后续演示扣减库存和生成订单的原子性操作。
CREATE TABLE products ( product_id INT PRIMARY KEY, product_name VARCHAR(128) NOT NULL, stock_qty INT CHECK (stock_qty >= 0), price DECIMAL(10,2) ); CREATE TABLE orders ( order_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, user_id INT NOT NULL, order_status VARCHAR(20) DEFAULT 'CREATED', total_amount DECIMAL(12,2), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE order_items ( item_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, order_id BIGINT NOT NULL REFERENCES orders(order_id), product_id INT NOT NULL, quantity INT NOT NULL, unit_price DECIMAL(10,2) );主键我用了自增列,而不是 UUID 或者雪花 ID。这个选择的理由很实在:对于订单这种高频率插入的表,基于序列的自增主键在索引叶节点上是顺序写入的,能有效减少页分裂,避免随机 IO。我见过不少团队一上来就用 UUID 做主键,数据量大了之后索引膨胀得厉害。如果确实需要全局唯一的业务订单号,建议单独建一个号段字段加唯一约束,不要把大字段直接塞进主键索引。
2.1 事务边界与并发控制实测
接下来是核心的下单事务。一个完整的下单操作要同时完成三件事:插入订单头、插入订单明细、扣减商品库存。这三步必须在同一个事务里,任何一个环节失败都要整体回滚。
BEGIN; INSERT INTO orders(user_id, total_amount) VALUES(1001, 299.00) RETURNING order_id; INSERT INTO order_items(order_id, product_id, quantity, unit_price) VALUES(1001, 20250101, 2, 149.50); UPDATE products SET stock_qty = stock_qty - 2 WHERE product_id = 20250101 AND stock_qty >= 2; COMMIT;这里最容易被忽略的是 UPDATE 语句里的stock_qty >= 2条件。它利用了数据库行锁的机制,在更新前自动判断库存是否充足。如果库存不足,影响行数为 0,应用层可以据此判断并回滚事务。这种写法比先 SELECT 再 UPDATE 的流程更安全,避免了在并发环境下读到过期库存的问题。
2.2 隔离级别与事务实操心得
我用的 YashanDB 默认事务隔离级别是读已提交,这个级别在绝大多数业务场景下都够用,而且并发性能比可串行化要好很多。对于订单扣库存这类场景,关键不在于隔离级别更高,而在于要确保更新操作尽量走索引,并且事务所占时间尽可能短。任何多余的网络往返或者慢查询都会放大锁竞争的几率。
实操建议:下单事务里不要混入外部接口调用,比如发短信、调支付回调。这些操作应该放在事务提交之后异步执行,否则事务的锁持有时间会被无谓拉长,高并发下很容易出现锁等待超时。
我还测了一下 YashanDB 在并发插入热点行时的表现。当多个会话同时更新同一个商品编号的库存时,系统会有锁等待机制,等待超时后会返回错误。这时应用层要做好重试策略,不要一报错就把整个事务丢弃。我习惯在应用侧给写操作配置两到三次重试,间隔以毫秒级别递增,实测能明显降低偶发失败率。
3. 示例二:零售销售分析中的窗口函数与物化视图
第二个示例转向分析场景。业务背景是一家连锁零售企业,需要按天统计各门店的销售情况,并产出环比和排名的报表。这个场景在 YashanDB 里最合适的实现方式是用窗口函数加物化视图,既能保证查询的灵活性,又能通过预计算提升性能。
我沿用示例一的订单明细表结构,额外增加一个销售事实表,用来记录已经发生的销售流水。这张表我做了范围分区,按月分区存储。对于分析查询来说,分区裁剪可以减少大量无效 IO。
CREATE TABLE sales_daily ( sale_date DATE NOT NULL, store_id INT NOT NULL, product_id INT NOT NULL, sale_qty INT, sale_amount DECIMAL(12,2) ) PARTITION BY RANGE (sale_date) INTERVAL (NUMTOYMINTERVAL(1,'MONTH')); CREATE INDEX idx_sales_daily_ds ON sales_daily(sale_date, store_id);注意PARTITION BY RANGE后面的INTERVAL子句,它实现了区间分区的自动扩展。每个月的数据会自动落入对应的分区,不需要 DBA 手工去创建新分区。这个功能对运维来说非常省心,我见过太多传统数据库因为忘了建分区导致某个月份的数据全部堆在默认分区里,查询性能直线下降。
3.1 门店销售排名的窗口函数写法
需求是统计每个门店在最近 30 天的累计销售额,同时给出排名,并计算每个门店销售额占全公司总额的百分比。用窗口函数实现最为简洁:
SELECT store_id, SUM(sale_amount) AS total_amount, RANK() OVER (ORDER BY SUM(sale_amount) DESC) AS rank_no, ROUND(SUM(sale_amount) / SUM(SUM(sale_amount)) OVER () * 100, 2) AS pct FROM sales_daily WHERE sale_date >= CURRENT_DATE - INTERVAL '30' DAY GROUP BY store_id ORDER BY rank_no;这里解释两个容易懵的地方。RANK()窗口函数在 GROUP BY 之后执行,所以窗口里的ORDER BY SUM(sale_amount)是直接对聚合结果排序的。而SUM(SUM(sale_amount)) OVER ()这种嵌套写法,外层 SUM 是窗口聚合,内层 SUM 是分组聚合,先按门店汇总,再对所有门店的汇总值做总体求和,从而计算出占比。
3.2 物化视图加速高频报表
日报表每天会被 BI 系统反复查询多次,每次都现场聚合几百万行数据,成本太高。更合适的做法是把聚合结果预先算好,存成物化视图。YashanDB 支持物化视图的增量刷新,当基表数据变化时,可以自动同步更新。
CREATE MATERIALIZED VIEW mv_store_sales_daily REFRESH FAST ON DEMAND AS SELECT sale_date, store_id, SUM(sale_qty) AS total_qty, SUM(sale_amount) AS total_amount, COUNT(*) AS order_cnt FROM sales_daily GROUP BY sale_date, store_id;查询报表时直接用物化视图,速度可以快一到两个数量级。但我提醒一句:物化视图不是建完就万事大吉的。REFRESH FAST要求基表有明确的变更记录机制,如果某些 DML 操作不支持增量刷新,系统会自动退化为全量刷新。我用的时候习惯先看执行计划里有没有出现MAT_VIEW REWRITE字样,确认查询真的走了重写,而不是还在扫底表。
3.3 分析场景的核心体会
分析型 SQL 的性能瓶颈大多不在数据库本身的执行引擎,而在于数据裁剪和聚合策略。我在示例里反复通过分区、索引、物化视图三层手段来压缩扫描量,就是为了说明这个道理。实际业务里,写 SQL 之前先问自己一句:这查询需要扫描多少数据?能通过分区裁剪掉 80% 吗?能用物化视图预聚合吗?思考清楚这几个问题,比调任何参数都管用。
YashanDB 的执行计划在复杂聚合下表现稳定,对于多表关联的查询,优化器会综合考虑数据分布来选连接顺序。我建议你在自己的测试环境里多对比一下改写前后的执行计划,找到最适合你数据量级的那条路。
4. 示例三:IoT 设备数据接入中的 JSON 半结构化存储
第三个示例是我最近项目里实际遇到的问题。物联网设备上报的数据,字段经常变动,今天多一个温度,明天多一个电压,用传统关系模型去维护一套固定字段的表,会被频繁的 DDL 改动折磨到崩溃。这时候 JSON 类型的价值就体现出来了。
YashanDB 的 JSON 类型实现不是把 JSON 当作大字符串存进去那么简单,它内部做了类型解析,支持对 JSON 字段建立索引,并且能用 SQL 函数直接提取 JSON 里的元素。我模拟一张设备上报表:
CREATE TABLE device_reports ( report_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, device_id VARCHAR(64) NOT NULL, report_time TIMESTAMP NOT NULL, payload JSON, CONSTRAINT uk_device_time UNIQUE(device_id, report_time) ); INSERT INTO device_reports(device_id, report_time, payload) VALUES ('DEV-0001', CURRENT_TIMESTAMP, '{"temp": 23.5, "humidity": 60, "battery": 88, "signal": {"rssi": -45, "snr": 12}}');JSON 的威力在于写代码的人自由度很高。设备固件升级之后新增字段,不需要同步修改数据库表结构,只需要让上报的数据里多带两个字段即可。这种模式在接入设备种类繁多、协议各异的场景下尤其适用。
4.1 JSON 字段提取与条件过滤
查询某台设备最近上报的温度和电量,可以用点号路径提取 JSON 内部字段:
SELECT device_id, report_time, payload.temp AS temperature, payload.battery AS battery_pct FROM device_reports WHERE device_id = 'DEV-0001' AND payload.temp > 20 ORDER BY report_time DESC LIMIT 10;payload.temp这种写法在 YashanDB 里是合法的,它把 JSON 对象里的temp字段当作虚拟列来使用。更复杂一点的场景,比如过滤嵌套 JSON 数组里的元素,就要用到 JSON_TABLE 这类函数去展开。我建议在业务设计阶段就把 JSON 的访问路径约定好,用注释写清楚每个路径对应的业务含义,不然过两个月连自己都记不清payload里的某个字段是嵌套在哪个层级。
4.2 半结构化数据的索引策略
JSON 字段直接建索引,是我强烈推荐的做法。对payload.temp这类高频过滤字段,可以单独建立索引:
CREATE INDEX idx_device_temp ON device_reports (payload.temp);这行 SQL 的效果等价于把 JSON 里的温度值提取出来,做成一个独立的 B 树索引。查询时条件里带有payload.temp > 20,优化器就会自动选择这个索引,避免对整张表的 JSON 字段做全量解析。
不过要话分两头说。JSON 虽然灵活,但也不是万金油。频繁用于关联、排序和统计的字段,长期看还是应该抽成普通列。我在实际项目中有一条经验法则:如果某个 JSON 字段在 80% 以上的查询里都会被访问,那就把它提出来建普通列,JSON 只留那些真正随版本演进的扩展属性。这样既保持了灵活性,又让优化器有更多的统计信息可以用。
4.3 设备数据写入的并发避坑
IoT 场景的写入通常是大批量、小事务。我在测试中发现,逐条 INSERT 在数据量上去后明显力不从心,改用手动提交的多行 INSERT,性能有显著提升。YashanDB 对多值 INSERT 的优化执行路径比单条插入要高效很多。
INSERT INTO device_reports(device_id, report_time, payload) VALUES ('DEV-0002', CURRENT_TIMESTAMP, '{"temp": 18.2, "humidity": 55}'), ('DEV-0003', CURRENT_TIMESTAMP, '{"temp": 21.0, "humidity": 48}'), ('DEV-0004', CURRENT_TIMESTAMP, '{"temp": 19.7, "humidity": 52}');大批量写入时还要注意归档日志的膨胀。如果连续导入几千万行 JSON 数据,观察一下日志切换频率和磁盘占用。归档日志增长太快会拖慢写入速度,必要时可以在导入窗口内临时调整日志相关参数,等导入结束后再改回来。
5. 示例四:连锁门店的地理空间检索与选址分析
第四个示例是关于空间数据的。背景是一个连锁品牌需要在城市里找新门店的选址,核心需求是计算所有候选点位与现有门店、居民区、竞争对手之间的距离,筛选出合适的位置。传统做法是用经纬度计算两点间距离,但在数据库里直接做空间对象运算会更方便,YashanDB 提供了标准的空间数据类型和配套索引。
先看建表的核心部分。我创建了一张门店表,地理位置字段用的是地理坐标类型,同时建立空间索引用于后续的快速检索。
CREATE TABLE store_locations ( store_id INT PRIMARY KEY, store_name VARCHAR(100), location GEOGRAPHY(POINT), address VARCHAR(256) ); CREATE INDEX idx_store_geo ON store_locations(location);这里的GEOGRAPHY(POINT)表示该字段存储地理坐标点数据,底层是按经纬度做存储的。空间索引则会把坐标点组织成适合范围检索的结构,避免计算每条记录时都做全局运算。这个设计思想类似于普通表里用 B 树加速等值查询,只不过空间索引加速的是"在某个范围里有哪些点"这类查询。
5.1 周边门店检索的查询示例
核心场景有两个。一个是给定一个经纬度坐标,查 5 公里范围内有哪些门店:
SELECT store_id, store_name, ST_Distance(location, ST_GeogFromText('POINT(116.397 39.908)')) AS dist_m FROM store_locations WHERE ST_DWithin(location, ST_GeogFromText('POINT(116.397 39.908)'), 5000) ORDER BY dist_m;ST_DWithin是在空间索引上执行的范围筛选,先通过索引粗筛出候选点,再精确计算距离并排序。第二个场景是计算两两门店之间的距离,常用于评估现有门店网络是否过于密集:
SELECT a.store_name AS store_a, b.store_name AS store_b, ST_Distance(a.location, b.location) AS dist_m FROM store_locations a JOIN store_locations b ON a.store_id < b.store_id WHERE ST_Distance(a.location, b.location) < 3000;自连接加上空间距离过滤,理论上计算量不小,但因为在连接过程里可以借助空间索引做裁剪,实际执行效率比我预想的要好。
5.2 坐标系与精度问题的经验总结
空间数据的使用,一个最容易被忽视的坑就是坐标系。不同数据源出来的经纬度,坐标系可能不一样,比如常见的 WGS-84 和 GCJ-02。如果混用没有统一的坐标基准,算出来的距离可能会偏差几百米甚至更多。我建议在数据入库阶段就统一完成坐标转换,数据库里全部存储同一种坐标系,后续所有计算都基于这个统一基准,这样既保证结果准确,也避免每次查询时做转换开销。
再补一个细节:GEOGRAPHY(POINT)计算出来的是球面距离,单位是米,适合城市范围内的距离评估,但如果数据横跨的经纬范围很大,球面模型的计算精度和性能表现会有差别。总的来说,门店选址这类城市级应用,直接用地理坐标类型就够了,不需要引入投影坐标那套更复杂的体系。
6. 示例五:大表运维中的在线索引重建与系统监控
最后一个示例和前四个不同,它展示的不是某个业务查询,而是日常运维和健康检查里最常用到的一类操作。业务数据库跑了一段时间之后,因为频繁的增删改,索引可能出现碎片,或者某张表的统计信息不再贴合真实数据分布,这时就需要 DBA 介入处理。
模拟场景是一张千万级流水表,由于历史原因,其二级索引创建得不太合适,我想在不中断业务的前提下重建索引。YashanDB 支持在线索引重建,这在实际生产环境里非常有用。
ALTER INDEX idx_orders_created_at REBUILD ONLINE;ONLINE关键字是关键。它表明重建过程中不会长时间锁定基表,业务读写可以继续执行。一般数据库里做这类操作,最怕锁表导致业务停顿,在线重建就是为了规避这个问题。即便如此,我仍然建议在业务低峰期执行,因为重建过程本身会消耗不少 IO 和 CPU 资源,峰值期跑在线重建还是可能拖慢核心交易。
6.1 统计信息更新与执行计划稳定
索引重建之外,另一个高频运维操作是收集统计信息。统计信息是优化器生成执行计划的重要依据。如果统计信息长时间不更新,优化器可能会因为对行数估计偏差而选错连接方式或者索引路径。YashanDB 提供计算统计信息的接口,可以对整表或单列做采样收集。
EXEC DBMS_STATS.GATHER_TABLE_STATS('APP', 'SALES_DAILY', CASCADE => TRUE);收集统计信息的操作比较耗时,但不需要特别频繁。我一般是这么定的节奏:大表每周一次,小表每三天一次,遇到批量数据加载完成之后再立即补一次。定期更新统计信息能让执行计划保持稳定,减少"昨天还快,今天突然变慢"这类玄学问题的出现。
6.2 健康检查脚本的核心维度
运维的日常不只是处理问题,更重要的是提前发现问题。我习惯定期查看系统视图,通过 SQL 直接了解表空间使用、活跃会话、锁等待等关键指标。
SELECT tablespace_name, used_space, max_size FROM dba_tablespace_usage_metrics; SELECT session_id, user_name, sql_id, status, wait_class FROM v$session WHERE status = 'ACTIVE';第一个查询用来判断表空间是否即将写满,第二个查询用来排查是否有会话长时间处于等待状态。锁等待这种事,越早发现越好,等业务方反馈"卡死了",往往已经锁了很长时间。
6.3 运维场景的实操心得
在线索引重建看似简单,但有个细节值得多说两句。重建之前先查一下目标索引的状态,确认它确实处于可用状态,只是碎片率高,才值得重建。如果索引本身已经处于不可用状态,那么REBUILD ONLINE可能无法直接执行,必须先改成离线重建或者用其他修复手段。
在线重建期间,监控日志里可能会看到等待事件,这属于正常现象,但要留意等待时间是否持续上涨。如果等待过长,说明系统资源已经紧张,可以考虑暂停或者分流。运维工作的核心目标不是背命令,而是理解每个操作在系统层面做了什么,代价是什么,收益是什么。理解了这三件事,遇到生产问题才能临危不乱。
7. 实践中容易踩的坑与问题排查速查
前面五个示例基本覆盖了 YashanDB 在不同类型场景下的使用方法,但真正到了现场实施的时候,总会遇到一些文档里没写透的细节。我把这段时间实测下来遇到过的比较典型的问题整理成一张速查表,方便你对照排查。
| 常见问题 | 典型表现 | 排查思路与解决方法 |
|---|---|---|
| 连接数打满 | 新应用连接被拒绝,报连接超限 | 查看连接数相关监控指标,排查是否存在连接泄漏,应用侧增加连接池复用,服务端调高上限 |
| 慢查询执行时间突增 | 原来毫秒级查询变成秒级 | 先看执行计划是否走了全表扫描,再检查统计信息是否需要刷新,最后排查索引是否失效 |
| 批量导入速度越来越慢 | 导入过程中吞吐量逐步下降 | 检查归档日志目录空间,观察是否有大量日志切换产生,必要时调整归档策略 |
| JSON 查询超出预期 | 带 JSON 条件的查询明显变慢 | 确认是否对 JSON 字段建立了必要索引,检查查询条件能否命中索引路径 |
| 空间查询结果偏差 | 距离计算结果与地图工具不一致 | 核对坐标系是否统一,确认数据坐标是否经过偏移处理 |
| 在线重建超时失败 | 重建索引任务执行中断 | 检查是否有大事务长时间占用相关对象,优先在业务低峰期操作并配置合理的超时时间 |
| 应用切换后报语法错误 | 原来数据库能跑的 SQL 迁移过来报错 | 核对 YashanDB 的兼容模式选项,确认 DDL 和函数写法是否正确,查看官方文档中的兼容性说明 |
这张表里的问题,一半属于使用习惯问题,另一半属于环境参数配置问题。大多数情况下,问题并不出在数据库本身。只要你在部署之前认真读一遍官方文档里的兼容性和参数配置章节,再结合你的具体业务做一遍压测,很多风险都能提前消除。
7.1 关于类型设计与转换的提醒
一个我在不同类型数据库之间迁移时经常遇到的坑,是字符集和类型映射的差异。比如原有系统里用VARCHAR2类型的字段,迁移到 YashanDB 之后要确认好对应类型长度定义是否一致,尤其是对中文字符的场景,字节长度与字符长度的问题如果搞错,很容易出现插入超长报错。
日期类型也需要特别留意。YashanDB 的日期时间类型精度默认到秒,如果你的业务需求精确到毫秒甚至微秒,建表时就要显式指定精度,否则毫秒部分会被截断。我有一个做订单系统的朋友,迁移后才发现时间字段的毫秒精度丢了,导致排序出现偏差,排查了很久才定位到是类型精度定义的问题。这类问题隐蔽性很强,建议大家在测试环境里先拿真实数据格式做一轮全量往返验证。
7.2 应用兼容性测试的三个阶段
国产数据库替换最怕的其实是应用层的兼容性问题。我建议按照"功能测试、性能测试、稳定性测试"三个阶段去推进。
功能测试阶段,把应用的 SQL 语句全部收集起来,在 YashanDB 上逐个跑一遍,确认语法和函数都能正确执行。性能测试阶段,用与生产接近的数据量做压测,重点观察慢查询、并发和锁等待指标。稳定性测试阶段,连续运行一周以上,模拟日常高峰流量,观察内存、磁盘、日志的长期趋势。三个阶段都通过,再谈正式切换的事。
注意事项:不要拿一个几十万行的测试库去验证千万级生产环境的性能表现。数据量不同,优化器对索引的选择和执行计划的走向都可能完全不同,测试结果几乎没有参考意义。
8. 从示例到落地的最后几点建议
写了这么多示例,其实我最想表达的一件事是:数据库的选型和落地,最终还是要把技术特性映射到具体的业务场景里去验证。YashanDB 的特性再好、参数再先进,如果你的业务场景根本用不上,那也白搭。反过来,只要在关键场景里通过了验证,那它的价值就是实打实的。
从我个人的实践经验来看,建议你先从高并发事务、复杂分析、半结构化数据处理这三个方向各挑一个最贴近业务的核心场景做试点,不要一下子把全部业务都迁移过来。试点期间把性能指标、兼容性问题、运维操作的体验都记录下来,形成一个完整的评估报告,再决定下一步的推进范围。这样做的好处是风险可控,即便遇到问题,也不会影响核心业务运行。
最后再分享一个小技巧。在正式使用 YashanDB 之前,最好先花半天时间把官方文档里的系统视图和动态性能视图清单过一遍。你不需要记住每个视图的每个字段,但至少要清楚哪些视图能看到连接会话、哪些视图能看到锁等待、哪些视图能看到表空间使用情况。等真的遇到生产问题需要排查时,你就会明白提前熟悉这些视图的价值有多大。应急场景里时间最宝贵,现查手册和直接敲 SQL,完全是两种效率。