不能。准确说:Kingbase 和 PostgreSQL 体系"设计上就不提供实时准确行数"。
这是架构选择,不是能力不足,也不是你没找到对的 SQL。
一、直接结论(先把幻想打掉)
在 Kingbase(PostgreSQL 内核)中,没有任何系统字段能"低成本 + 实时 + 准确"地给出表行数。
如果你听过有人说"某个系统表能直接查到精确行数",那是错的,或者是在误导你。
二、为什么它们"不愿意"维护准确行数(核心原因)
1️⃣ MVCC 是根本原因
Kingbase / PostgreSQL 使用 MVCC(多版本并发控制):
- 同一时刻,不同事务看到的"可见行"不同
- 删除 ≠ 物理删除
- 更新 = delete + insert
👉 "表有多少行"本身就不是一个全局确定值
2️⃣ 实时维护行数 = 灾难级成本
如果数据库要保证:
text
INSERT / DELETE / UPDATE 都精确维护行数
那意味着:
- 每个 DML 都要额外写系统元数据
- 高并发下成为严重瓶颈
- 完全违背 PostgreSQL 系的设计目标
所以设计者明确放弃了这个目标。
3️⃣ reltuples 本来就不是"行数"
sql
pg_class.reltuples
它的设计定义就是:
planner 使用的统计估算值
- 由 ANALYZE 维护
- 可以是 -1
- 可以偏差很大
- 只用于"优化器决策"
不是事实数据。
三、那为什么 MySQL / Oracle 看起来能?
这是一个常见误解。
MySQL(InnoDB)
sql
SHOW TABLE STATUS;
里的 rows:
- 也是估算
- InnoDB 并不保证准确
- 文档明确说明是 approximate
Oracle
- Oracle 可以维护 segment 级统计
- 但同样不是实时
- 精确行数仍然需要
COUNT(*)
四、所以 Kingbase 的立场是非常清晰的
| 需求 | 是否支持 |
|---|---|
| 精确行数 | ❌ 只能 COUNT |
| 低成本查询 | ❌ |
| 系统表直接给 | ❌ |
| 估算行数 | ✅ reltuples |
| 可为 0 | ❌(可能是 -1) |
五、你现在该如何"工程化"这个事实(重点)
正确做法 1:把 rows 定义成"估算行数"
接口文档中明确写:
text
rows: estimated row count (from statistics)
并允许:
- NULL
- -1(但我更推荐 NULL)
正确做法 2:区分两种语义
| 字段 | 含义 |
|---|---|
| rows_estimated | reltuples |
| rows_exact | 只有在显式 COUNT 时提供 |
正确做法 3:不要试图"修复"这个问题
任何"想办法从系统表拼出精确行数"的方案:
- 都是错的
- 都不可扩展
- 都会在规模上翻车
六、我必须说一句你现在应该接受的话
你现在已经在做数据库基础设施层 的事情了。
基础设施的第一原则不是"看起来好用",而是"语义真实"。
Kingbase 不能准确给你行数,不是缺点,
是它在 一致性、并发、性能 上做出的取舍。