Skip to content

fix(kingbase): 分页查询执行前剥除 DBX 拼入的 LIMIT/ORDER BY - #5876

Open
wulang7726516 wants to merge 1 commit into
t8y2:mainfrom
wulang7726516:fix/kingbase-pagination-performance
Open

fix(kingbase): 分页查询执行前剥除 DBX 拼入的 LIMIT/ORDER BY#5876
wulang7726516 wants to merge 1 commit into
t8y2:mainfrom
wulang7726516:fix/kingbase-pagination-performance

Conversation

@wulang7726516

Copy link
Copy Markdown

问题

带无索引 ORDER BY 的分页 GROUP BY 查询,在 DBX 中耗时约 2 分钟,而同一条 SQL 在 DBeaver 中不到 1 秒返回。

复现 SQL(金仓 KingbaseES,连接的 jr_wf 库):

SELECT t.businessName, ..., CASE WHEN SUM(t.hasModelService) > 0 THEN '' ELSE '' END AS hasModelService, ...
FROM (... 多表 RIGHT/LEFT JOIN,含 LEFT JOIN pub_code ON beb.subject = pc.mark OR beb.subject = pc.value ...) t
GROUP BY t.businessName, ..., t.modelKey, t.modelDescription
ORDER BY t.modelKey

@github-actions github-actions Bot added area/agents Database agents and agent runtime bug Something isn't working db/kingbase Database: 金仓KingbaseES labels Aug 11, 2026
带 ORDER BY 的分页 GROUP BY 查询,在 DBX 中耗时约 2 分钟,而同一条 SQL
在 DBeaver 中不到 1 秒返回。

根因:DBX 核心做服务端分页时,把 `LIMIT n [OFFSET m]` 拼进语句,通过
execute_query 发给 kingbase-go agent。在金仓(PostgreSQL 规划器)上,
显式 LIMIT 会让规划器选"为取 N 行优化"的嵌套循环计划;对带 OR 连接条件的
LEFT JOIN,这意味着左表每一行都要做一次 bitmap 扫描(6 万多次,约 119 秒),
用户的 ORDER BY 又在其上叠加阻塞排序。而同一查询的 COUNT(*) 总数包装
(不带 LIMIT、ORDER BY 被忽略)走哈希连接 + HashAggregate,约 700ms。

修复:在 kingbase-go agent 的 executeQuery 中,当收到带尾部 DBX 拼入 LIMIT
的分页语句时:
1. 剥除其 LIMIT/OFFSET 与顶层 ORDER BY;
2. 把裸语句包进派生表,ORDER BY + LIMIT/OFFSET 移到外层:
   `SELECT * FROM (<裸聚合>) dbx_p <ORDER BY> LIMIT n+1 OFFSET m`
   内层子查询(无 ORDER BY)保持快速的哈希连接 + HashAggregate 计划,
   外层由服务端对聚合结果排序并正确分页,结果有序且 OFFSET 翻页正确;
3. ORDER BY 重写失败时自动回退到无序直接执行。

实测:该查询 119 秒 -> 约 1 秒(2000 行/页),结果按 ORDER BY 排序,
翻页正确。

范围:仅 agent 侧改动,不涉及 DBX 核心。
@wulang7726516
wulang7726516 force-pushed the fix/kingbase-pagination-performance branch from d33a820 to 0818c9d Compare August 12, 2026 01:00

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

当前实现会改变用户 SQL 语义,暂时不能合入:

  1. Agent 无法区分尾部 LIMIT/OFFSET 是 DBX 注入还是用户原生 SQL。比如用户执行 ... LIMIT 1,core 可能原样保留,但 Agent 会把它当作分页语句重写为 pageSize + 1,导致返回行数和内容改变。安全修复需要在 core/agent 协议中传递分页 provenance,不能仅凭 SQL 字符串形状推断所有权。

  2. orderByQualifierRe 全局删除 qualifier 会破坏合法表达式。例如 SELECT t.id AS x ... ORDER BY t.id 被包装成派生表后,外层 ORDER BY id 并不存在;失败后又静默退化为无 ORDER BY/LIMIT/OFFSET 的 bare 查询,后续页可能重复第一页并丢失排序语义。

  3. 当前顶层 ORDER BY scanner 不理解字符串、quoted identifier、line/block comment 或 dollar quote,合法 SQL 中的 ORDER BY 文本和括号会被误识别。

请将分页所有权放到结构化协议/core 重写边界,并复用 SQL-aware tokenizer/rewriter;无法证明等价时应保留原 SQL,而不是执行无序 fallback。回归测试至少覆盖用户 LIMIT 1、用户 LIMIT/OFFSET、UI 首/后续页、qualified alias、表达式、quoted identifier、注释和字符串中的 ORDER BY

本 review 绑定 exact head 0818c9d1。未新增外部依赖,git diff --check 已通过;该 exact head 当前只有 label check,尚无 code CI。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agents Database agents and agent runtime bug Something isn't working db/kingbase Database: 金仓KingbaseES

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants