Oracle SQL 优化知识库:构建方案与价值评估

Oracle SQL 优化知识库:构建方案与价值评估

文档类型 :方案宣讲(讲清楚为什么做、怎么做、优缺点)

适用场景 :团队评审、技术分享、方案汇报

配套文档 :plans/DESIGN-QDRANT-INTEGRATION.md(技术设计)、plans/SPRINT-PDF-INGESTION.md(实施计划)

数据来源:所有数字来自实际工具输出(ingest_report.md / 落盘测试日志),可追溯


一、为什么需要构建知识库

1.1 问题:纯 LLM 优化 SQL 的根本缺陷

SQLAdvisor 的核心功能是"用 LLM 优化 Oracle SQL"。但直接让 LLM 改写 SQL 有一个根本缺陷:

LLM 的优化建议没有权威依据,全凭模型自身记忆。

具体表现:

问题 后果
LLM 可能编造 Oracle 不支持的语法/hint 生成的 SQL 在 Oracle 上报错或无效
LLM 的优化建议泛泛而谈("加索引"、"改写子查询") 缺乏具体到 Oracle 版本的准确指导
LLM 不知道 Oracle 12c 的特定特性(如自适应优化、SQL Plan Baseline) 错过版本专属的优化机会
不同 LLM、不同会话给出不一致的建议 优化质量不稳定,不可复现
无法解释"为什么这样优化" 用户不敢采纳,优化建议缺乏可信度

本质:LLM 是个"学过很多但记不准"的顾问。没有权威知识约束,它会把模糊记忆当事实输出------这在数据库优化这种"差一个 hint 就差 10 倍性能"的场景下是危险的。

1.2 知识库解决什么

把 Oracle 官方文档 (SQL Tuning Guide,724 页权威指南)结构化成知识库,让 LLM 在改写 SQL 时先检索权威依据,再生成建议:

复制代码
没有知识库:  用户SQL → LLM(凭记忆)→ 优化建议(可能编造)
有了知识库:  用户SQL → 检索官方文档 → LLM(基于权威依据)→ 优化建议(有出处)

核心价值:把 LLM 从"凭记忆的顾问"变成"查了手册的顾问"。

1.3 为什么选 Oracle 12c SQL Tuning Guide

理由 说明
权威性 Oracle 官方出版(E49106-14, July 2017),是 Oracle SQL 调优的权威指南
系统性 24 章 + 附录,覆盖优化器、统计信息、执行计划、访问路径、连接、并行、SQL Profile 等全链路
版本匹配 项目测试库是 Oracle 18.4 XE(12c 架构延续),文档适用
结构清晰 有完整目录(outline),便于按章节抽取,天然适合知识库构建
公开可得 Oracle 官网公开 PDF,无版权障碍(内部使用)

二、如何构建知识库

2.1 整体方案:PDF → 结构化知识 → 向量库

2.1.1 全景流程图

核心思路:把一本 724 页的 PDF 官方手册,经过 提取 → 切片 → 抽取 → 验证 → 导出 五步,变成可被 Agent 检索、可追溯、抗编造的结构化知识库。

复制代码
┌─────────────────────────────────────────────────────────────────┐
│  Oracle 官方 PDF                                                 │
│  《SQL Tuning Guide》12c Release 1                               │
│  724 页 · 24 章 · outline 1027 条目录                            │
└────────────────────────────┬────────────────────────────────────┘
                             │
              ┌──────────────▼──────────────┐
              │ ① 文本提取(Stage A)         │  pdfplumber 逐页提取
              │   + 章节归属解析              │  pypdf outline 解析目录
              └──────────────┬──────────────┘
                             │ 724 页原文(697 有效 + 27 跳过)
                             │  每页带 section_path(如 "Ch.11 Histograms")
              ┌──────────────▼──────────────┐
              │ ② 章节切片(Stage B)         │  按 outline 章节边界分组
              │   token 感知切块              │  目标 1200 token/片,重叠 150
              └──────────────┬──────────────┘
                             │ 308 个 chunks
                             │ 覆盖 1-24 章 + 附录全部
              ┌──────────────▼──────────────┐
              │ ③ LLM 智能抽取(Stage C)     │  每片喂 GLM-4-flash
              │   强制 source_quote          │  要求输出结构化 JSON
              │   + 自动 quote 校正          │  每条必须带原文引用
              └──────────────┬──────────────┘
                             │ 1031 条原始条目
                             │ 4 类:规则/解释/语法/示例
              ┌──────────────▼──────────────┐
              │ ④ 五层验证 + 去重清洗          │  L0 完整性 / L1 一致性
              │   (详见 §2.3)               │  L2 语义 / L3 反向 / L4 人工
              │   + 字段清洗 + 强去重         │  剔除 102 条无法回溯的
              └──────────────┬──────────────┘
                             │ 847 条验证后的知识
                             │ 带质量分级(verified/disputed)
              ┌──────────────▼──────────────┐
              │ ⑤ 多目标导出(Stage E)       │  一次构建,四处消费
              └─┬─────────┬──────────┬───────┴──────────┬──────────┘
                ▼         ▼          ▼                  ▼
          ┌─────────┐ ┌─────────┐ ┌──────────────┐ ┌──────────────┐
          │rules.json│ │ SQLite  │ │ Markdown     │ │ Qdrant       │
          │ 372 条   │ │ 847 行  │ │ 33 个章节文件 │ │ 847 points   │
          │ 规则引擎 │ │ 结构化  │ │ 人工审查     │ │ 向量检索     │
          │ 源      │ │ 查询    │ │              │ │ (Agent RAG)  │
          └─────────┘ └─────────┘ └──────────────┘ └──────────────┘
2.1.2 数据流转:每一步的输入、处理、输出
步骤 输入 关键处理 输出 淘汰/损耗
① 文本提取 724 页 PDF pdfplumber 逐页提文字;pypdf 解析 outline 建"页→章节"映射(含前向继承:章节标题后的所有页继承该章节,直到下个标题) 697 页有效文本 + 27 页跳过(封面/目录/扉页) 27 页低信息密度页(合理跳过,有清单可查)
② 章节切片 697 页文本 按 outline 章节边界分组;章节内按 token 累积切(1200 token/片,150 重叠防截断);跳过 <100 token 的过短片(封面/分隔页) 308 个 chunks 4 个过短 chunk 跳过
③ LLM 抽取 304 个有效 chunks 每个 chunk 喂 GLM-4-flash,要求:识别优化规则/语法/示例/概念 → 输出结构化 JSON → 每条必须带 source_quote(≥20 字原文精确引用);同时跑 quote 自动校正(LCS 算法把改写过的引用对齐回原文) 1031 条原始条目 1 个 chunk 抽取超时失败(附录 A 索引指南,显式记录)
④ 验证去重 1031 条原始条目 L1:回原文验证 source_quote(90.1% 通过,剔除 102 条无法回溯的编造);L2:LLM 二次校验忠实度;字段清洗(修复类型错放);强去重(标题归一化相等合并) 847 条验证后条目 102 条 L1 剔除 + 82 条强重复合并 + 4 条 quote 不可验证
⑤ 多目标导出 847 条最终条目 safety 闸门过滤 example_sql(145 条危险 SQL 过滤);并行导出 4 种格式 rules.json(372) + SQLite(847) + Markdown(33 文件) + Qdrant(847 points) 145 条 example_sql 被 backend 安全闸门过滤(保留条目本体,只清空 example_sql 字段)
2.1.3 关键技术决策(为什么这么做)
决策 选择 为什么不选另一方案
切片粒度 1200 token/片 + 150 重叠 太小(如 500 token):切碎语义,LLM 抽取上下文不足;太大(如 3000 token):超出 LLM 有效注意力,抽取质量下降。重叠 150 防"建议被切到两半"
切片边界 按 outline 章节边界优先,章节内再按 token 纯滑窗(无视章节):会把"直方图"和"统计信息"混在一个 chunk,LLM 抽取混乱;按章节优先:语义连贯
抽取模型 GLM-4-flash(OpenAI 兼容) 用规则/正则提取:无法理解语义,抓不住"建议"这种主观表述;用大模型(GPT-4):成本高 10 倍,且 flash 对结构化抽取够用
防编造机制 强制 source_quote + 自动回溯 不强制引用:LLM 会用自己的话概括,无法验证是否忠实原文;强制引用让每条知识都可追溯到 PDF 页码
embedding 模型 GLM embedding-3(dim 2048) BGE-M3(本地):需下载 2GB 模型,HuggingFace CDN 在当前网络不可达;GLM 在线 API:国内可访问,已验证可用
向量库 Qdrant(独立 collection) 不用向量库(纯关键词检索):抓不住语义相似("全表扫描" vs "table access full");Qdrant 独立 collection:不污染现有 oracle_best_practices
去重策略 标题归一化强去重(不用语义去重) 语义去重(embedding 相似度):需加载 embedding 模型,慢且有误判风险;强去重:确定性强,可复现
导出多目标 一次构建导出 4 种格式 只导向量库:规则引擎/人工审查/结构化查询都用不了;多目标:同一份知识适配不同消费场景
2.1.4 质量闸门分布(数据在哪里被淘汰)

从 1031 条原始抽取到 847 条最终条目,每一步的淘汰都有据可查(不静默丢弃):

复制代码
1031 条原始抽取
   │
   ├─ L1 剔除     -102 条(source_quote 无法回溯原文 → 疑似编造)
   │              清单: l1_mismatches.jsonl(可审查每条为何被剔)
   │
   ├─ 强去重合并   -82 条(标题归一化后重复)
   │
   └─▶ 847 条进入最终产物
        │
        ├─ L2 disputed 253 条(保留但标 ⚠️,不剔除------降级可见)
        │   清单: l2_disputes.jsonl
        │
        └─ safety 过滤 145 条 example_sql(条目保留,只清空示例 SQL 字段)
            原因: 含 DDL/多语句等,被 backend 四层安全闸门拦截

原则 :所有淘汰/降级都在报告和清单文件中显式列出,不折叠为泛化的"success"。任何一条被剔除的知识都能查到原因。

2.2 五阶段构建管线

阶段 做什么 工具 产出
A. 文本提取 PDF 每页提取文字 + 解析目录建立章节归属 pdfplumber + pypdf 724 页原文(697 有效页 + 27 跳过页)
B. 章节切片 按章节边界 + token 长度切成知识片段 tiktoken(1200 token/片,150 重叠) 308 个 chunks,覆盖 1-24 章全部
C. LLM 抽取 每个片段让 GLM-4 提取结构化知识(规则/语法/示例) GLM-4-flash(OpenAI 兼容) 1031 条结构化条目
D. 去重清洗 标题去重 + 字段清洗 + 严重度归一 Python 规则 + 启发式 847 条最终条目
E. 多目标导出 同时导出 4 种格式供不同场景消费 httpx + SQLite + json rules.json / SQLite / Markdown / Qdrant

2.3 五层质量验证(核心:防止 LLM 编造)

构建知识库最大的风险是 LLM 在抽取过程中编造内容(把模糊记忆当文档内容输出)。为此设计了五层验证:

层 验证什么 怎么验 结果
L0 完整性 PDF 有没有漏页、产物数量一致 机械计数:dedup=SQLite=Qdrant=847 ✓ 全过
L1 一致性(防编造底座) 每条知识能不能回溯到 PDF 原文 强制 source_quote 字段,自动回原文做子串匹配 90.1% 通过(剔除 102 条无法回溯的)
L2 语义校验 抽取是否忠实原文(非语义篡改) 第二轮 LLM 独立评判每条 582 verified + 253 disputed(全保留降级)
L3 反向覆盖 PDF 要点有没有被遗漏 反向抽样:每章抽页列要点,查是否被覆盖 70% 覆盖,0 critical 遗漏
L4 人工抽检 最终可信度 50 条人工对照 PDF 原文核对 96% 全对(48/50)

关键设计------L1 强制回溯 :每条抽取的知识必须带一句 source_quote(≥20 字,必须是 PDF 原文精确子串)。系统自动回 PDF 原文验证这句引用是否真实存在------这一层拦住了绝大多数 LLM 编造。

2.4 最终知识库内容(847 条)

类型 数量 说明 示例
optimization_rule 372 优化规则(可被规则引擎/RAG 用) "索引列避免函数,或用函数索引 FBI"
explanation 350 概念解释 "什么是直方图、成本估算原理"
syntax_doc 95 语法说明 "CREATE INDEX 语法、DBMS_STATS 调用"
example_sql 30 完整示例 SQL(已过安全闸门) 频率直方图生成示例

每条知识都带:

  • source_page(PDF 页码,可追溯)
  • source_quote(原文精确引用)
  • category(INDEX/STATISTICS/JOIN/OPTIMIZER 等 14 类)
  • severity(INFO/WARN/ERROR,optimization_rule 专属)
  • quality_flag(verified/disputed,质量分级)

2.5 构建耗时与成本(真实数据)

项 耗时 说明
文本提取(724 页) ~10 分钟 pdfplumber
LLM 抽取(308 片段) ~3.5 小时 GLM-4-flash,含网络重试
L1-L4 验证 ~1.5 小时 自动 + 人工抽检
总计 ~5 小时 一次性构建,后续可增量
GLM 调用次数 ~3000 次 抽取 + 二次校验
成本 数元级别 glm-4-flash 单价低

三、知识库如何被使用

3.1 集成到 Agent 主优化流程

用户提交 SQL 后,Agent 在让 LLM 改写之前,先检索知识库找相关权威依据:

复制代码
用户: SELECT * FROM orders WHERE UPPER(customer_name) = 'ACME'
                    │
    Agent 自动检索知识库(用 SQL 语义匹配)
                    │
                    ▼
    命中: [INDEX] 索引列上避免函数(或用函数索引 FBI)
          "WHERE UPPER(name)='X' 会使 name 上的普通 B-tree 索引失效"
          来源: Oracle 12c SQL Tuning Guide p.211
                    │
                    ▼
    注入到 LLM prompt: <knowledge> 索引列避免函数... </knowledge>
                    │
                    ▼
    LLM 生成变体: CREATE INDEX idx_cust_upper ON orders(UPPER(customer_name));
                  SELECT * FROM orders WHERE UPPER(customer_name) = 'ACME';
    (变体的 rationale 引用了知识库依据,不再是凭空建议)

3.2 多种使用方式

方式 场景 怎么用
Agent 自动接地(已集成) 主优化流程 调 /api/optimize,RAG 自动注入,用户无感
向量检索(Qdrant) 语义查询"如何优化 X" 按 SQL/关键词检索,返回最相关的 top-N 条
结构化查询(SQLite) 精确查某类规则/某页内容 SQL 查询 oracle_12c_kb.db,按 category/severity 过滤
人工查阅(Markdown) 学习/审查 33 个按章节组织的 topics-*.md,每条带原文引用
规则引擎源(rules.json) 补充 AST 规则 372 条 optimization_rule,backend rules.json 兼容格式

四、使用知识库的优点

4.1 优化建议有权威依据(核心价值)

维度 无知识库 有知识库
建议来源 LLM 模糊记忆 Oracle 官方文档原文
可追溯性 无法验证 每条建议带 PDF 页码 + 原文引用
版本准确性 可能混淆版本 锁定 Oracle 12c 特性
可信度 用户不敢采纳 用户可查原文确认

4.2 LLM 编造被有效抑制

L1 强制回溯机制(每条知识必须引用 PDF 原文)让知识库本身抗编造。Agent 基于这样的知识库生成建议,等于给 LLM 加了"必须引用手册"的约束。

4.3 知识可复用、可审计

构建一次(5 小时),多处消费:

  • Agent 主流程用(RAG 接地)
  • 未来 chatbot 用(语义问答)
  • 规则引擎用(372 条规则)
  • 人工查阅用(Markdown)
  • 质量可审计(五层验证,每条可追溯到 PDF 页)

4.4 构建过程可复现、可增量

  • 全流程代码化(ingestion 包),可重新构建
  • 断点续跑(大文件中断可恢复)
  • 第二本 PDF(SQL Language Reference,1920 页)同管线,配置已就绪

五、使用知识库的缺点与局限

诚实评估------知识库不是银弹,以下局限必须知晓。

5.1 检索质量受 query 构造影响(当前主要痛点)

问题:用原始 SQL 做 embedding query 效果一般。SQL 的语法噪音(SELECT/FROM/WHERE)淡化了优化意图。

实例 :查 SELECT * FROM employees WHERE UPPER(name)='SMITH',理想是命中"函数索引"那条规则,实际命中的是泛化的"Querying Table Information"(score 0.53)。

影响:注入 LLM 的知识不一定是最相关的,优化建议的针对性打折。

缓解方向 :改用 rule_findings(AST 规则发现文本)或 SQL 特征描述做 query,而非 raw SQL。

5.2 引入额外延迟和依赖

代价 量级 说明
每次优化多 ~0.5s GLM embedding 0.45s + Qdrant 检索 0.05s 用户感知不明显,但高并发下累积
依赖 GLM embedding API 在线服务 API 不可达时降级为纯 LLM(不阻塞,但失去接地)
依赖 Qdrant 服务 独立进程 Qdrant 宕机时同样降级

5.3 知识库覆盖率非 100%

  • L3 反向覆盖率 70%(非 80% 门槛):抽样发现的 191 个 minor 遗漏(多为细分要点),无 critical 遗漏,但意味着部分次要知识点未被独立抽取
  • L4 人工抽检 96%(2 条字段错放):质量高但非完美
  • 253 条 disputed(L2 有疑虑):保留但标 ⚠️,使用前建议人工核对

5.4 构建前期投入大

  • 5 小时构建(含 LLM 抽取 + 验证)------虽然是一次性,但比"直接用 LLM"重得多
  • 需要 PDF 原文------必须先有权威源文档
  • 需要 GLM API 额度------抽取+校验约 3000 次调用

5.5 embedding 方案的运维复杂度

  • 知识库用 GLM embedding(dim 2048),与 backend 原有 BGE-M3(dim 1024)不兼容
  • 必须按 collection 选择 embedding 模型,配置不能错(错了维度不匹配,查询失效)
  • 切换 embedding 模型需重建整个向量库

5.6 仅覆盖一本 PDF(当前)

当前只构建了 SQL Tuning Guide(724 页)。SQL Language Reference(1920 页,语法大全)尚未构建(管线已就绪,待启动)。语法类问题目前知识库覆盖不足。


六、总结:值不值得做

6.1 价值矩阵

维度 评分 说明
解决编造问题 ★★★★★ L1 强制回溯 + L2 二次校验,从源头抑制 LLM 编造
提升建议可信度 ★★★★★ 每条建议可追溯到 Oracle 官方文档页码
构建成本 ★★★☆☆ 5 小时 + 3000 次 API,一次性投入,可接受
检索质量 ★★★☆☆ 当前 query 构造偏弱,有改进空间
运维复杂度 ★★★☆☆ 多了 Qdrant + GLM embedding 依赖,但有降级容错
覆盖范围 ★★★★☆ 724 页已覆盖调优核心,1920 页语法待补

6.2 适用与不适用场景

适合用知识库:

  • 数据库优化这种"权威性要求高、错误代价大"的领域
  • 有权威源文档(官方手册、标准规范)可抽取
  • 用户需要"为什么这样优化"的可解释性
  • 优化建议需要版本准确(Oracle 12c 特性)

不适合用知识库:

  • 没有权威文档的领域(LLM 记忆已是最佳来源)
  • 一次性快速验证(构建 5 小时太重)
  • 实时性要求极高(检索增加 0.5s 延迟)
  • 领域知识频繁变化(知识库需频繁重建)

6.3 结论

值得做。对于 SQLAdvisor 这类数据库优化工具,知识库把 LLM 从"不可控的顾问"变成"查了手册的顾问"------这是从"能用"到"敢用"的关键一步。5 小时构建成本相比"用户不敢采纳优化建议"的代价是划算的。

当前主要改进方向是检索质量 (query 构造)和覆盖范围(第二本 PDF),这些是增量优化,不影响"知识库本身值得构建"的基本判断。


附录:核心数字速查(全部实测,可追溯)

指标 数值 来源
PDF 页数 724 pypdf 实测
知识片段数 308 chunker 产出
原始抽取条目 1031 extractor 产出
最终知识条目 847 extracts_dedup.json
optimization_rule 372 type 统计
L1 一致性通过率 90.1%(929/1031) l1_verified.jsonl 计数
L2 verified 582 quality_flag 统计
L2 disputed(保留降级) 253 quality_flag 统计
L3 反向覆盖率 70.0%(449/641) l3_coverage_gaps.json
L3 critical 遗漏 0 l3_coverage_gaps.json
L4 人工抽检通过率 96%(48/50) l4_audit_50.csv
四产物一致性 ✓(dedup=SQLite=Qdrant=847) 实测
构建总耗时 ~5 小时 实际运行
Agent 测试 14/14 passed(41.45s) 落盘测试日志
相关推荐
茉莉玫瑰花茶2 小时前
OpenGL [ 基础概念 ]
java·前端·数据库
温暖小土2 小时前
Spring AI 接入 DeepSeek Chat 模型
数据库·人工智能·spring
张小姐的猫2 小时前
【AI大模型接入SDK】 —— 前端页面 & 项目总结与拓展
前端·数据结构·数据库·c++·人工智能·chatgpt
IvorySQL2 小时前
去 IOE 的最后一公里:IvorySQL 5.4 × RISC-V 实测
数据库·人工智能·ai·postgresql·risc-v
-madongyu-2 小时前
HCIE-GaussDB V2.0 笔试考点总览:模块权重、核心要点与高频数字速记
数据库·华为·gaussdb
我的愿望是成为富婆2 小时前
HR数字化校招技术栈拆解:SQL、Excel、Power BI和AI工具在2026届JD中的真实权重
人工智能·sql·excel
LRL_2 小时前
Oracle 19c 创建用户并连接 PDB 完整避坑指南
数据库·oracle
雨落在了我的手上2 小时前
MySQL数据库基础(3):库的操作
数据库