perf(dameng): defer cold query metadata until after execution

This commit is contained in:
zipg
2026-10-14 16:25:44 +08:00
committed by GitHub
parent 3e9974b226
commit cfdcd9041b
5 changed files with 532 additions and 2 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

@@ -0,0 +1,369 @@
{
"date": "2026-10-14",
"environment": {
"database": "DM8",
"driver": "DmJdbcDriver8 8.1.5.45",
"runtime": "JDK 21",
"tableColumns": 301,
"tableRows": 10000,
"returnedRows": 100,
"scope": "actual queryStore with a thin JSON-RPC adapter to the current-source Dameng agent; no Web/Tauri UI or Rust HTTP transport"
},
"before": [
{
"name": "normal-cold",
"metadataDelayMs": 0,
"autoCommit": true,
"resultElapsedMs": 87.56,
"rows": 100,
"primaryKeys": [
"ID"
],
"events": [
{
"operation": "columns:start",
"elapsed": 4.7
},
{
"operation": "indexes:start",
"elapsed": 4.87
},
{
"operation": "indexes:done",
"elapsed": 63.35
},
{
"operation": "columns:done",
"elapsed": 71.24
},
{
"operation": "execute:start",
"elapsed": 72.96,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 83.05,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
}
]
},
{
"name": "normal-cold-warm",
"resultElapsedMs": 6.61,
"rows": 100,
"hiddenColumnIndexes": [
4
],
"events": [
{
"operation": "execute:start",
"elapsed": 0.63,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 5.31,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
}
]
},
{
"name": "delayed-metadata-cold",
"metadataDelayMs": 2000,
"autoCommit": true,
"resultElapsedMs": 1022.49,
"rows": 100,
"primaryKeys": [
"ID"
],
"editability": "primary-key-not-returned",
"events": [
{
"operation": "columns:start",
"elapsed": 0.58
},
{
"operation": "indexes:start",
"elapsed": 0.65
},
{
"operation": "indexes:done",
"elapsed": 19.07
},
{
"operation": "execute:start",
"elapsed": 1003.38,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 1019.46,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "columns:done",
"elapsed": 2021.75
}
]
},
{
"name": "delayed-metadata-cold-warm",
"resultElapsedMs": 18.82,
"rows": 100,
"hiddenColumnIndexes": [
4
],
"events": [
{
"operation": "execute:start",
"elapsed": 0.89,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 17.18,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
}
]
},
{
"name": "delayed-metadata-manual",
"metadataDelayMs": 2000,
"autoCommit": false,
"resultElapsedMs": 1028.66,
"rows": 100,
"primaryKeys": [
"ID"
],
"editability": "primary-key-not-returned",
"events": [
{
"operation": "columns:start",
"elapsed": 0.93
},
{
"operation": "indexes:start",
"elapsed": 1.05
},
{
"operation": "indexes:done",
"elapsed": 17.26
},
{
"operation": "execute:start",
"elapsed": 1019.33,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 1026.43,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "columns:done",
"elapsed": 2018.76
}
]
},
{
"name": "delayed-metadata-manual-warm",
"resultElapsedMs": 14.67,
"rows": 100,
"hiddenColumnIndexes": [
4
],
"events": [
{
"operation": "execute:start",
"elapsed": 1.77,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 12,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
}
]
}
],
"after": [
{
"name": "normal-cold",
"metadataDelayMs": 0,
"autoCommit": true,
"resultElapsedMs": 49.94,
"rows": 100,
"primaryKeys": [
"ID"
],
"editability": "primary-key-not-returned",
"events": [
{
"operation": "execute:start",
"elapsed": 3.91,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 44.78,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "columns:start",
"elapsed": 49.72
},
{
"operation": "indexes:start",
"elapsed": 49.92
},
{
"operation": "indexes:done",
"elapsed": 78.93
},
{
"operation": "columns:done",
"elapsed": 86.36
}
]
},
{
"name": "normal-cold-warm",
"resultElapsedMs": 6.32,
"rows": 100,
"hiddenColumnIndexes": [
4
],
"events": [
{
"operation": "execute:start",
"elapsed": 0.93,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 5,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
}
]
},
{
"name": "delayed-metadata-cold",
"metadataDelayMs": 2000,
"autoCommit": true,
"resultElapsedMs": 5.58,
"rows": 100,
"primaryKeys": [
"ID"
],
"editability": "primary-key-not-returned",
"events": [
{
"operation": "execute:start",
"elapsed": 0.45,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 4.46,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "columns:start",
"elapsed": 5.47
},
{
"operation": "indexes:start",
"elapsed": 5.56
},
{
"operation": "indexes:done",
"elapsed": 25.31
},
{
"operation": "columns:done",
"elapsed": 2027.28
}
]
},
{
"name": "delayed-metadata-cold-warm",
"resultElapsedMs": 19.43,
"rows": 100,
"hiddenColumnIndexes": [
4
],
"events": [
{
"operation": "execute:start",
"elapsed": 1.27,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 17.63,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
}
]
},
{
"name": "delayed-metadata-manual",
"metadataDelayMs": 2000,
"autoCommit": false,
"resultElapsedMs": 21.89,
"rows": 100,
"primaryKeys": [
"ID"
],
"editability": "primary-key-not-returned",
"events": [
{
"operation": "execute:start",
"elapsed": 12.76,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 19.18,
"sql": "SELECT C1, C2, C3, C4 FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "columns:start",
"elapsed": 21.63
},
{
"operation": "indexes:start",
"elapsed": 21.85
},
{
"operation": "indexes:done",
"elapsed": 62.53
},
{
"operation": "columns:done",
"elapsed": 2064.44
}
]
},
{
"name": "delayed-metadata-manual-warm",
"resultElapsedMs": 13.84,
"rows": 100,
"hiddenColumnIndexes": [
4
],
"events": [
{
"operation": "execute:start",
"elapsed": 0.8,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
},
{
"operation": "execute:done",
"elapsed": 12.25,
"sql": "SELECT C1, C2, C3, C4, \"ID\" AS \"__DBX_PK_0\" FROM SYSDBA.T10308W FETCH FIRST 100 ROWS ONLY"
}
]
}
]
}
@@ -0,0 +1,43 @@
# 达梦查询元数据异步化实测(2026-10-14)
## 环境和边界
- 本地 `dm8_demo` 容器,DM Database Server 64 V8,构建标识 `03134284094-20230927-203585-20067`。
- 本次工作区源码构建的 Dameng JDBC agent,JDK 21,DmJdbcDriver8 8.1.5.45。
- 复用只读测试表 `SYSDBA.T10308W`:301 列、10,000 行,返回前 100 行。
- 运行实际 `useQueryStore().executeTabSql()`;临时 Vitest 驱动只把后端 API 映射到真实 agent JSON-RPC,SQL、列和索引均由真实达梦返回。SQL 分析使用现有前端分析器。
- 未启动 Web/Tauri 客户端或 Rust HTTP 网关,数字不包含真实 HTTP 传输和界面渲染。连接已打开;“冷”指表元数据缓存为空。
- 对照使用主线 `184b55c89`;优化使用同一主线上的改动。每个场景为一次时序校验,不能作为普遍性能增幅的统计结论。
## SQL
```sql
SELECT C1, C2, C3, C4
FROM SYSDBA.T10308W
FETCH FIRST 100 ROWS ONLY
```
## 结果
| 场景 | 改动前:结果可用 | 改动后:结果可用 |
| --- | ---: | ---: |
| Normal cold metadata | 87.56 ms | 49.94 ms |
| Metadata response +2s | 1022.49 ms | 5.58 ms |
| Metadata +2s, manual TX | 1028.66 ms | 21.89 ms |
额外 2 秒是测试驱动在真实 `get_columns` 响应之后注入的延迟,不是达梦实测的自然元数据耗时。对照路径会先发列/索引请求,等待约 1 秒的预检预算;优化后先发 SQL,结果返回后才发元数据请求。
![首次结果等待时间](../assets/pr-dameng-query-metadata/first-result-latency.png)
## 校验内容
- 正常、慢元数据、手动事务三个场景均返回真实 100 行,列数据一致。
- 优化后每个冷缓存场景均满足 `execute:done` 早于 `columns:start` 和 `indexes:start`。
- 元数据未准备好时结果已可读,不对缺少主键的结果开启编辑。
- 元数据准备好后再次查询命中缓存,SQL 补入 `"ID" AS "__DBX_PK_0"`,隐藏列索引为 4,恢复编辑,未重复读取列元数据。
- 手动事务通过真实 agent 的 `begin_manual_transaction` 开始,读完后回滚。
- 修改前后各 3 个实测场景通过。另有元数据失败、过期响应、JDBC profile 和手动事务的常规回归测试。
完整时间戳及 SQL 记录见 [live-results.json](../assets/pr-dameng-query-metadata/live-results.json)。
此结果证明移除了达梦冷元数据对 SQL 派发的依赖,**未复现也未宣称解决 #10308 中 280–300 秒的完整生产延迟**。旧游标关闭、驱动及服务端查询耗时仍是独立排查方向。