Oracle执行计划优化SPM案例

2024-04-18 03:52

本文主要是介绍Oracle执行计划优化SPM案例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.现象

执行下面这段代码,发现子库存表走了全表扫描

SELECT msi.secondary_inventory_name, --子库存msi.description --库存说明FROM inv.mtl_secondary_inventories msi,csi_item_instances            ciiWHERE msi.secondary_inventory_name = cii.inv_subinventory_nameAND msi.secondary_inventory_name IS NOT NULL

在这里插入图片描述
子库存表里面的索引
在这里插入图片描述
于是我们加上库存组织后再进行查询
在这里插入图片描述
仍旧是全表扫描
这时我们使用hint语法,强制走索引
在这里插入图片描述

2.确认hint文实际生效

我们在客户端按F5,显示的是解释计划,如果我们要看真正的执行计划,需要使用xplan方法

SELECT /*TOTO20210526*/ /*+ gather_plan_statistics */
/*+ index(msi MTL_SECONDARY_INVENTORIES_U1)*/msi.secondary_inventory_name, --子库存msi.description --库存说明FROM inv.mtl_secondary_inventories msi,csi_item_instances            ciiWHERE msi.secondary_inventory_name = cii.inv_subinventory_name--and msi.organization_id=cii.inv_organization_id

我们使用魔术注释,然后查询下面SQL

SELECT t.*FROM v$sql s,table(DBMS_XPLAN.DISPLAY_CURSOR(s.sql_id, s.child_number)) tWHERE sql_text LIKE '%TOTO20210526%';

在这里插入图片描述
可以看到确实走了索引。但是使用hint,只是告诉了成本优化器要这么做。此时一种方法是直接改写代码中的sql加上这个hint,然后重新部署上线。第二种方法就是利用SPM固定带有hint的执行计划。

3.查询计划基线

即使在xplan中显示已经使用了索引,但是除非是该计划基线已经被固定,否装不会使用该执行计划
我们打开一个新窗口,执行下面语句,捕获计划

alter session set optimizer_capture_sql_plan_baselines =true;

执行查询语句

SELECT /*TOTO20210526-4*/
/*+ index(msi MTL_SECONDARY_INVENTORIES_U1)*/msi.secondary_inventory_name, --子库存msi.description --库存说明FROM inv.mtl_secondary_inventories msi,csi_item_instances            ciiWHERE msi.secondary_inventory_name = cii.inv_subinventory_nameand msi.organization_id=cii.inv_organization_idAND msi.secondary_inventory_name IS NOT NULL

关闭捕获

alter session set optimizer_capture_sql_plan_baselines =false;

查询计划基线

select ENABLED, --    指示计划基准是已启用(YES)还是已禁用(NO)ACCEPTED, --   表示计划基线是否被接受(YES)否(NO)FIXED, --    指示计划基准是否固定(YES)(NO) spb.*from dba_sql_plan_baselines spb;

在这里插入图片描述
上图sql_text内容就是我们的SQL文本
查询该计划基线对应的执行计划,将SQL_HANDLE传入

select * from table(dbms_xplan.DISPLAY_SQL_PLAN_BASELINE('SYS_SQL_b06e9c3ae9259fe3'));

在这里插入图片描述
可以看出已经使用了索引,上图有一个Plan hash value: 1786343847
我们也可以执行下列查询

select * from V$SQL_PLAN s where s.PLAN_HASH_VALUE='1786343847'

4.固定计划基线

我们将sql_handle作为参数,在sysdba角色下执行下列脚本,固定计划基线,优化完成。

declare 
l_plans_altered pls_integer;begin
l_plans_altered:=dbms_spm.alter_sql_plan_baseline(sql_handle      =>'SYS_SQL_b06e9c3ae9259fe3' ,plan_name       =>null ,attribute_name  =>'fixed' ,attribute_value =>'YES' );
end;DECLAREreport CLOB;
BEGINreport := dbms_spm.evolve_sql_plan_baseline(sql_handle => 'SYS_SQL_b06e9c3ae9259fe3');dbms_output.put_line(report);
END;

5.收集统计信息(补充)

很多情况下,没有走理想的索引和计划是由于统计信息过旧导致的,数据库体量允许的情况下,可以重新收集统计信息。
比如此案例中CBO基于错误的或者历史的统计信息,判断子库存表全表扫描速度更快。
收集索引统计信息dbms_stats.gather_index_stats(‘schema’, ‘table_name’);

BEGINdbms_stats.gather_table_stats(ownname          => 'INV',tabname          => 'MTL_SECONDARY_INVENTORIES',estimate_percent => dbms_stats.auto_sample_size,method_opt       => 'FOR ALL COLUMNS SIZE AUTO');
END;

这篇关于Oracle执行计划优化SPM案例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/913694

相关文章

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Python get()函数用法案例详解

《Pythonget()函数用法案例详解》在Python中,get()是字典(dict)类型的内置方法,用于安全地获取字典中指定键对应的值,它的核心作用是避免因访问不存在的键而引发KeyError错... 目录简介基本语法一、用法二、案例:安全访问未知键三、案例:配置参数默认值简介python是一种高级编