21-Oracle 23 ai-Automatic SQL Plan Management(SPM)
小伙伴们,有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL,
性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。
于是SPM定位开始,OCM考试中SPM必考。
其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题,下次填坑。
Oracle SQL Plan Management(SPM)是一种通过控制执行计划稳定性来优化SQL性能的内置机制,其核心原理是通过基线(Baseline)机制管理执行计划的演进,避免因计划突变导致的性能下降。
一、使用场景
- 基线(Baseline)机制:记录已知性能良好的执行计划,新生成的计划需验证性能后才被采纳。
- 演进控制:新计划必须证明优于或等于基线计划,否则仍使用原计划。
二、关键组件
- Plan History:存储SQL所有曾使用的执行计划(包括未验证的)。
- Plan Baseline:Plan History的子集,仅包含已验证(ACCEPTED)且稳定的高效计划。
- SQL Management Base :存储SPM元数据的字典表(位于SYSAUX表空间)。
三、原理解析:工作流程
1. 计划捕获(Plan Capture)
- 自动捕获 (需设置参数OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES=TRUE):
- 首次执行的SQL生成计划后,该计划作为初始基线(标记为ENABLED和ACCEPTED)。
- 后续新计划进入Plan History,但状态为ENABLED, NOT ACCEPTED,需经性能验证才可加入基线。
- 手动捕获:
- 通过DBMS_SPM包从共享池、SQL调优集(STS)或存储大纲导入计划。
2. 计划选择(Plan Selection)
- 优化器决策流程(需启用OPTIMIZER_USE_SQL_PLAN_BASELINES=TRUE):
-
- 若存在ACCEPTED计划 → 直接使用该计划。
- 若新计划不在Baseline中 → 将其加入Plan History(状态为NOT ACCEPTED)。
-
- 若新计划性能劣化(如逻辑读激增),自动回退至Baseline中的最优计划。
3. 计划演进(Plan Evolution)
- 自动演进:
- 任务SYS_AUTO_SPM_EVOLVE_TASK定期检查未ACCEPTED的计划,通过性能对比(如CPU时间、I/O消耗)决定是否采纳。
- 参数ACCEPT_PLANS控制是否自动接受更优计划(默认TRUE)。
- 手动演进:
- 使用 DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE()测试并接受新计划。
四、Oracle 23 ai 的SPM特性增强:
- 变化:新增实时检测和修复性能退化的执行计划,无需等待自动任务或手动干预。从捕获、验证到演进全程自动化,减少人工维护成本。
- 原理:持续监控SQL执行性能,若新计划比基线计划慢,自动回退到基线计划并标记新计划为"UNACCEPTED"。深度集成SQL Monitor,秒级检测执行计划性能退化,自动切换至历史最优计划,无需DBA干预。
- 优势:减少因计划突变导致的性能风险,尤其适合关键业务SQL。
- 变化:SPM可管理含AI向量搜索的SQL执行计划(如"VECTOR_DISTANCE()"函数)。
- 原理:优化器为向量搜索SQL生成计划时,SPM基线会记录并验证其效率。
- 示例场景:相似性搜索(如"WHERE VECTOR_DISTANCE(embedding, :vec) < 1")的计划稳定性增强。
- 变化:在Globally Distributed Database中,SPM基线支持跨分片同步。
- 原理:通过Raft共识协议复制基线计划,确保分布式环境下计划一致性。
- 变化:SPM优先选择利用In-Memory列存储(如内存连接组)的高效计划。
- 原理:当"INMEMORY_AUTOMATIC_LEVEL=HIGH"时,SPM自动采纳内存优化计划。
五、配置和实操
1. 启用实时SPM
-- 启用自动捕获SQL计划基线
SYS@FREE> ALTER SYSTEM SET OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES = TRUE;
System altered
-- 启用实时SPM(默认开启,验证状态)
SYS@FREE> SELECT value FROM v$parameter WHERE name = 'optimizer_use_sql_plan_baselines';
VALUE
------------------------------------------------------------------------------------------------------------------------
TRUE
-- 返回值应为 TRUE
2. 验证实时SPM回退机制
-- 步骤1: 创建测试表
CREATE TABLE spm_test (id NUMBER, data VARCHAR2(100));
INSERT INTO spm_test SELECT rownum, 'Data'||rownum FROM dual CONNECT BY LEVEL <= 10000;
COMMIT;-- 步骤2: 首次执行(生成初始计划)
SYS@CDB$ROOT> SELECT /*+ REAL_TIME_SPM_TEST */ * FROM spm_test WHERE id = 500;ID DATA
______ __________500 Data500-- 步骤3: 可以尝试删除索引
DROP INDEX IF EXISTS spm_test_idx;-- 先创建索引再删除
CREATE INDEX spm_test_idx ON spm_test(id); -- 先创建索引再删除,模拟计划突变-- 步骤4: 再次执行相同SQL
SELECT /*+ REAL_TIME_SPM_TEST */ * FROM spm_test WHERE id = 500;
-- 观察执行计划是否回退到全表扫描(原最优计划为索引扫描)
3. 监控SPM状态
--- 查看已捕获的SQL计划基线,查询 SPM 捕获结果
SELECT sql_handle, plan_name, enabled, accepted,optimizer_cost,origin AS capture_source -- 显示来源为 REAL-TIME
FROM dba_sql_plan_baselines
WHERE sql_text LIKE '%REAL_TIME_SPM_TEST%';SQL_HANDLE PLAN_NAME ENABLED ACCEPTED OPTIMIZER_COST CAPTURE_SOURCE
_______________________ _________________________________ __________ ___________ _________________ _________________
SQL_64b41bf95ca6b6c6 SQL_PLAN_69d0vz5faddq691cb0adf YES NO 2 AUTO-CAPTURE
SQL_64b41bf95ca6b6c6 SQL_PLAN_69d0vz5faddq696d17023 YES YES 1 AUTO-CAPTURE
SQL_64b41bf95ca6b6c6 SQL_PLAN_69d0vz5faddq6f2fc655a YES NO 9 AUTO-CAPTURE
SQL_b1986790bdca8230 SQL_PLAN_b3637k2ywp0jh6ded1a00 YES YES 2 AUTO-CAPTURE
SQL_6cf7d7301796c616 SQL_PLAN_6txyr60btdjhq6ded1a00 YES YES 2 AUTO-CAPTURE
SQL_9b8aec55051bcab5 SQL_PLAN_9r2rcan2jrkpp6ded1a00 YES YES 2 AUTO-CAPTURE
SQL_9cd99fe508c1b86c SQL_PLAN_9tqczwn4c3f3cb73cade2 YES YES 0 AUTO-CAPTURE
--
-- 检查实时回退事件
SELECT sql_id, PLAN_HASH_VALUE
FROM v$sql
WHERE sql_text LIKE '%REAL_TIME_SPM_TEST%';
--
SQL_ID PLAN_HASH_VALUE
________________ __________________
aq357chxcs0kd 903671040
6xphsvkrns1q1 2664986145
g86t44cwf41r8 2664986145
g03qt7845c4pv 903671040
ajhtavdx2s5t9 2664986145
6kma5qad96t0n 2664986145
6kma5qad96t0n 2664986145
111gdsdj2ft3g 1155944573
6110vngy8zkm4 9036710409 rows selected.-- 方案1:SQL Monitor报告(需SQL_ID)
SELECT DBMS_SQL_MONITOR.REPORT_SQL_MONITOR(sql_id => '161f318vx0y63') FROM DUAL;
-- 报告中的Note部分会标注SPM回退事件
SYS@CDB$ROOT> SELECT DBMS_SQL_MONITOR.REPORT_SQL_MONITOR FROM DUAL;
REPORT_SQL_MONITOR
_______________________________________________________________________________________________________________________________
SQL Monitoring Report
SQL Text
------------------------------
begin dbms_swrf_internal.awr_imp(dmpfile=> :mpk_name, dmpdir=>:mbloc, new_dbid=>:dbid, mbtype=>:mbtype, mbcred=>:cred); end;
Global Information
------------------------------Status : DONEInstance ID : 1Session : SYS (205:3673)SQL ID : 161f318vx0y63SQL Execution ID : 16777217Execution Started : 06/08/2025 19:58:55First Refresh Time : 06/08/2025 19:59:00Last Refresh Time : 06/08/2025 19:59:01Duration : 6sModule/Action : MMON_SLAVE/AWR Warehouse Auto-ImportService : SYS$BACKGROUNDProgram : oracle@OL96 (M003)Global Stats
===============================================================================================================
| Elapsed | Cpu | IO | Application | Concurrency | Other | Buffer | Read | Read | Write | Write |
| Time(s) | Time(s) | Waits(s) | Waits(s) | Waits(s) | Waits(s) | Gets | Reqs | Bytes | Reqs | Bytes |
===============================================================================================================
| 6.65 | 5.70 | 0.07 | 0.00 | 0.75 | 0.12 | 108K | 1468 | 19MB | 1 | 8192 |
===============================================================================================================-- 方案2:检查计划基线状态
SELECT sql_handle, plan_name, enabled, accepted, origin
FROM DBA_SQL_PLAN_BASELINES
WHERE sql_text LIKE '%REAL_TIME_SPM_TEST%'
AND origin = 'AUTO-CAPTURE';
-- 若accepted=YES且origin为自动捕获,说明回退成功
----- 检查演进任务报告
SYS@CDB$ROOT> SELECT DBMS_SPM.report_auto_evolve_task FROM dual;REPORT_AUTO_EVOLVE_TASK
________________________________________________________________________________________________
GENERAL INFORMATION SECTION
---------------------------------------------------------------------------------------------Task Information:---------------------------------------------Task Name : SYS_AUTO_SPM_EVOLVE_TASKTask Owner : SYSDescription : Automatic SPM Evolve TaskExecution Name : EXEC_280Execution Type : SPM EVOLVEScope : COMPREHENSIVEStatus : COMPLETEDStarted : 06/08/2025 14:00:13Finished : 06/08/2025 14:00:14Last Updated : 06/08/2025 14:00:14Global Time Limit : 3600Per-Plan Time Limit : UNUSEDNumber of Errors : 0
---------------------------------------------------------------------------------------------SUMMARY SECTION
---------------------------------------------------------------------------------------------Number of plans processed : 0Number of findings : 0Number of recommendations : 0Number of errors : 0
---------------------------------------------------------------------------------------------
SYS@CDB$ROOT>
六、高级管理脚本
1. 手动固定最优计划
--- 查找SQL的SQL_HANDLE
DECLAREl_plans PLS_INTEGER;
BEGINl_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id => 'XXXXXXX' -- 替换为实际SQL_ID);
END;
/
2. 主动演化计划基线
--- 测试并采纳新计划
SYS@CDB$ROOT> SET SERVEROUTPUT ON
SYS@CDB$ROOT> DECLARE2 r_report CLOB;3 BEGIN4 r_report := DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(5 sql_handle => 'SQL_9cd99fe508c1b86c' -- 替换为实际SQL_HANDLE6 );7 DBMS_OUTPUT.PUT_LINE(r_report);8 END;9* /
GENERAL INFORMATION SECTION
---------------------------------------------------------------------------------------------Task Information:---------------------------------------------Task Name : TASK_362Task Owner : SYSExecution Name : EXEC_322Execution Type : SPM EVOLVEScope : COMPREHENSIVEStatus : COMPLETEDStarted : 06/09/2025 14:58:35Finished : 06/09/2025 14:58:35Last Updated : 06/09/2025 14:58:35Global Time Limit : 2147483646Per-Plan Time Limit : UNUSEDNumber of Errors : 0
---------------------------------------------------------------------------------------------SUMMARY SECTION
---------------------------------------------------------------------------------------------Number of plans processed : 0Number of findings : 0Number of recommendations : 0Number of errors : 0
---------------------------------------------------------------------------------------------PL/SQL procedure successfully completed.SYS@CDB$ROOT>
七、验证建议
- 1.使用EXPLAIN PLAN FOR对比回退前后的执行计划差异。
- 2.结合V$SQL_PLAN和DBA_SQL_PLAN_BASELINES验证计划切换记录。
- 3.在测试环境模拟高并发场景,观察SPM对稳定性的提升效果。

相关文章:

21-Oracle 23 ai-Automatic SQL Plan Management(SPM)
小伙伴们,有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL, 性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。 于是SPM定位开始,OCM考试中SPM必考。 其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题…...

性能优化中,多面体模型基本原理
1)多面体编译技术是一种基于多面体模型的程序分析和优化技术,它将程序 中的语句实例、访问关系、依赖关系和调度等信息映射到多维空间中的几何对 象,通过对这些几何对象进行几何操作和线性代数计算来进行程序的分析和优 化。 其中࿰…...

【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战
🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...

二维数组 行列混淆区分 js
二维数组定义 行 row:是“横着的一整行” 列 column:是“竖着的一整列” 在 JavaScript 里访问二维数组 grid[i][j] 表示 第i行第j列的元素 let grid [[1, 2, 3], // 第0行[4, 5, 6], // 第1行[7, 8, 9] // 第2行 ];// grid[i][j] 表示 第i行第j列的…...

HTML版英语学习系统
HTML版英语学习系统 这是一个完全免费、无需安装、功能完整的英语学习工具,使用HTML CSS JavaScript实现。 功能 文本朗读练习 - 输入英文文章,系统朗读帮助练习听力和发音,适合跟读练习,模仿学习;实时词典查询 - 双…...

【threejs】每天一个小案例讲解:创建基本的3D场景
代码仓 GitHub - TiffanyHoo/three_practices: Learning three.js together! 可自行clone,无需安装依赖,直接liver-server运行/直接打开chapter01中的html文件 运行效果图 知识要点 核心三要素 场景(Scene) 使用 THREE.Scene(…...

C#中用于控制自定义特性(Attribute)
我们来详细解释一下 [AttributeUsage(AttributeTargets.Class, AllowMultiple false, Inherited false)] 这个 C# 属性。 在 C# 中,Attribute(特性)是一种用于向程序元素(如类、方法、属性等)添加元数据的机制。Attr…...

2025 后端自学UNIAPP【项目实战:旅游项目】7、景点详情页面【完结】
1、获取景点详情的请求【my_api.js】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http(/login/getWXSessionKey, {code,avatar}); };//…...

项目进度管理软件是什么?项目进度管理软件有哪些核心功能?
无论是建筑施工、软件开发,还是市场营销活动,项目往往涉及多个团队、大量资源和严格的时间表。如果没有一个系统化的工具来跟踪和管理这些元素,项目很容易陷入混乱,导致进度延误、成本超支,甚至失败。 项目进度管理软…...
iOS 项目怎么构建稳定性保障机制?一次系统性防错经验分享(含 KeyMob 工具应用)
崩溃、内存飙升、后台任务未释放、页面卡顿、日志丢失——稳定性问题,不一定会立刻崩,但一旦积累,就是“上线后救不回来的代价”。 稳定性保障不是某个工具的功能,而是一套贯穿开发、测试、上线全流程的“观测分析防范”机制。 …...
02-性能方案设计
需求分析与测试设计 根据具体的性能测试需求,确定测试类型,以及压测的模块(web/mysql/redis/系统整体)前期要与相关人员充分沟通,初步确定压测方案及具体的性能指标QA完成性能测试设计后,需产出测试方案文档发送邮件到项目组&…...
window 显示驱动开发-如何查询视频处理功能(三)
D3DDDICAPS_GETPROCAMPRANGE请求类型 UMD 返回指向 DXVADDI_VALUERANGE 结构的指针,该结构包含特定视频流上特定 ProcAmp 控件属性允许的值范围。 Direct3D 运行时在D3DDDIARG_GETCAPS的 pInfo 成员指向的变量中为特定视频流的 ProcAmp 控件属性指定DXVADDI_QUER…...
MySQL基本操作(续)
第3章:MySQL基本操作(续) 3.3 表操作 表是关系型数据库中存储数据的基本结构,由行和列组成。在MySQL中,表操作包括创建表、查看表结构、修改表和删除表等。本节将详细介绍这些操作。 3.3.1 创建表 在MySQL中&#…...

JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除
目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作…...
SpringCloud优势
目录 完善的微服务支持 高可用性和容错性 灵活的配置管理 强大的服务网关 分布式追踪能力 丰富的社区生态 易于与其他技术栈集成 完善的微服务支持 Spring Cloud 提供了一整套工具和组件来支持微服务架构的开发,包括服务注册与发现、负载均衡、断路器、配置管理等功能…...
Electron简介(附电子书学习资料)
一、什么是Electron? Electron 是一个由 GitHub 开发的 开源框架,允许开发者使用 Web技术(HTML、CSS、JavaScript) 构建跨平台的桌面应用程序(Windows、macOS、Linux)。它将 Chromium浏览器内核 和 Node.j…...

深入理解 C++ 左值右值、std::move 与函数重载中的参数传递
在 C 编程中,左值和右值的概念以及std::move的使用,常常让开发者感到困惑。特别是在函数重载场景下,如何合理利用这些特性来优化代码性能、确保语义正确,更是一个值得深入探讨的话题。 在开始之前,先提出几个问题&…...
【大厂机试题解法笔记】矩阵匹配
题目 从一个 N * M(N ≤ M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。 输入描述 输入矩阵要求:1 ≤ K ≤ N ≤ M ≤ 150 输入格式 N M K N*M矩阵 输…...

java 局域网 rtsp 取流 WebSocket 推送到前端显示 低延迟
众所周知 摄像头取流推流显示前端延迟大 传统方法是服务器取摄像头的rtsp流 然后客户端连服务器 中转多了,延迟一定不小。 假设相机没有专网 公网 1相机自带推流 直接推送到云服务器 然后客户端拉去 2相机只有rtsp ,边缘服务器拉流推送到云服务器 …...

免费批量Markdown转Word工具
免费批量Markdown转Word工具 一款简单易用的批量Markdown文档转换工具,支持将多个Markdown文件一键转换为Word文档。完全免费,无需安装,解压即用! 官方网站 访问官方展示页面了解更多信息:http://mutou888.com/pro…...
【Redis】Redis从入门到实战:全面指南
Redis从入门到实战:全面指南 一、Redis简介 Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,它可以用作数据库、缓存和消息代理。由Salvatore Sanfilippo于2009年开发,因其高性能、丰富的数据结构和广泛的语言支持而广受欢迎。 Redis核心特点:…...
LeetCode 0386.字典序排数:细心总结条件
【LetMeFly】386.字典序排数:细心总结条件 力扣题目链接:https://leetcode.cn/problems/lexicographical-numbers/ 给你一个整数 n ,按字典序返回范围 [1, n] 内所有整数。 你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法。…...
智能体革命:企业如何构建自主决策的AI代理?
OpenAI智能代理构建实用指南详解 随着大型语言模型(LLM)在推理、多模态理解和工具调用能力上的进步,智能代理(Agents)成为自动化领域的新突破。与传统软件仅帮助用户自动化流程不同,智能代理能够自主执行工…...

以太网PHY布局布线指南
1. 简介 对于以太网布局布线遵循以下准则很重要,因为这将有助于减少信号发射,最大程度地减少噪声,确保器件作用,最大程度地减少泄漏并提高信号质量。 2. PHY设计准则 2.1 DRC错误检查 首先检查DRC规则是否设置正确,然…...
linux设备重启后时间与网络时间不同步怎么解决?
linux设备重启后时间与网络时间不同步怎么解决? 设备只要一重启,时间又错了/偏了,明明刚刚对时还是对的! 这在物联网、嵌入式开发环境特别常见,尤其是开发板、树莓派、rk3588 这类设备。 解决方法: 加硬件…...

若依项目部署--传统架构--未完待续
若依项目介绍 项目源码获取 #Git工具下载 dnf -y install git #若依项目获取 git clone https://gitee.com/y_project/RuoYi-Vue.git项目背景 随着企业信息化需求的增加,传统开发模式存在效率低,重复劳动多等问题。若依项目通过整合主流技术框架&…...
零基础在实践中学习网络安全-皮卡丘靶场(第十一期-目录遍历模块)
经过前面几期的内容我们学习了很多网络安全的知识,而这期内容就涉及到了前面的第六期-RCE模块,第七期-File inclusion模块,第八期-Unsafe Filedownload模块。 什么是"遍历"呢:对学过一些开发语言的朋友来说应该知道&…...
mcts蒙特卡洛模拟树思想
您这个观察非常敏锐,而且在很大程度上是正确的!您已经洞察到了MCTS算法在不同阶段的两种不同行为模式。我们来把这个关系理得更清楚一些,您的理解其实离真相只有一步之遥。 您说的“select是在二次选择的时候起作用”,这个观察非…...

华为云Flexus+DeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手
华为云FlexusDeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手 一、构建知识库问答助手引言二、构建知识库问答助手环境2.1 基于FlexusX实例的Dify平台2.2 基于MaaS的模型API商用服务 三、构建知识库问答助手实战3.1 配置Dify环境3.2 创建知识库问答助手3.3 使用知…...
Qt学习及使用_第1部分_认识Qt---Qt开发基本流程
前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾…...