拓扑园

  • O&M
    • Universal部署
    • PHP+VUE+Laravel相关
  • Oracle性能优化
  • Oracle项目案例
    • Oracle近期项目案例(目录)
    • Oracle实战问题解析(目录)
    • Oracle数据库名变更流程(2种方式)
    • Oracle数据库目录更换流程(使用Oracle的clone工具)
    • Oracle数据库迁移方案(目录)
    • 标准化文档系列
  • Oracle基础知识
    • LLL的Oracle培训(分类)
    • LLL的docker培训(分类)
    • 标准化文档系列--(分类)
    • Oracle核心经典分析(分类)
    • 图灵小队----(分类并包含以下文章)
    • --MySQL8.0/Oracle/Memcached/Redis等安装配置于RHEL/OL6/7/8.X系列-运行环境最优配置
    • --PG安装配置于RHEL/9X系列-运行环境最优配置
    • --自动维护任务详解-开启、关闭信息统计收集(统计信息)
    • --图灵小队—Oracle/PostgreSQL下创建一个用户测试表(自行定义数据行)
    • --图灵小队-Oracle存储过程导出表的明细_UTL_FILE(文章)
    • --图灵小队-Oracle数据库删除/卸载操作指南(文章)
    • --图灵小队-Oracle常用性能查询SQL语句(文章)
    • --图灵小队-Oracle数据库上线前检查(文章)
    • --图灵小队-Oracle常用SQL语句(文章)
    • --图灵小队—Linux/Oracle脚本/MySQL合集(持续更新)
    • --图灵小队-Oracle技巧记录(文章)
    • ADG
    • RAC
    • ASM
    • OGG
    • RMAN
    • EXPDP/IMPDP
    • 工厂数据导入导出系列
  • MySQL
    • MySQL数据库规范
    • MySQL项目案例
    • MySQL安装配置
    • MYSQL集群项目
    • MySQL常见处理
    • MySQL-Sysbench专题
    • MySQL-Percona Toolkit专题
  • Linux
    • Shell编程
    • kubernetes
    • docker
    • Linux
    • PHP
    • Nginx
    • haproxy
    • mail
    • 网站
    • 域名
    • 网址收藏
  • 数据中心
    • 新框架系统集合
    • 工作文档
    • EBS数据文件扩容
    • VMware虚拟化
    • EBS系列
    • 大数据
    • SVN
    • zabbix
    • SAP
    • 备份相关
    • FC交换机
    • SVN
  • K-Studing
    • D8-Python学习
    • Oracle/MySQl等面试题
    • LG-MySQL
    • LG-Docker/K8S
    • LG-PostgreSQL
    • LG-ORACLE_BBED
    • LG-ORACLE
    • LG-Elasticsearch(ES)+ELK
    • Oracle-19C-OCP
    • WERN_ORACLE培训
    • redis数据库
    • Nginx培训学习系列
  • 其他
    • 外研英语4年级下册-听力
    • 影视系列
    • 如何使用iTunes软件通过抓包下载旧版本的ios的app
天高任鸟飞
Oracle/MySQL数据库恢复/数据迁移/生产规范报告技术交流:TEL:18562510581(微信同号);加微信入群
  1. 首页
  2. Oracle基础知识
  3. 图灵小队
  4. 正文

使用SQL tuning advisor(STA)自动优化SQL——(未整理完成)

2022年1月20日 866点热度 0人点赞 0条评论

目录

  • 1、SQL tuning的基本步骤
  • 2、如何tuning SQL
  • 3、Automatic Tuning Optimizer 做什么?
    • (1)分析统计信息
    • (2)分析访问路径
    • (3)SQL结构分析
    • (4)SQL profiling
  • 4、Automatic Tuning Optimizer与SQL tuning advisor结构图
  • 5、STA可tuning的方式
  • 6、演示SQL tuning
    • (1)环境

Oracle 10g之后的优化器支持两种模式,一个是normal模式,一个是tuning模式。

在大多数情况下,优化器处于normal模式。基于CBO的normal模式只考虑很小部分的执行计划集合用于选择哪个执行计划,因为它需要在尽可能短的时间,通常是几秒或毫秒级来对当前的SQL语句进行解析并生成执行计划。因此并不能保证SQL语句每次都是使用最佳的执行计划。

而tuning模式则将高负载的SQL语句直接扔给优化器,优化器来自动对其进行详细的分析,调试并给出建议,这就是Oracle 提供的Automatic Tuning Optimizer,即自动调整优化器。Oracle 自动调整优化器通过SQL调优建议器(SQL tuning advisor)来体现。

1、SQL tuning的基本步骤

(1)鉴别需要调整的高负载SQL或者Top SQL
(2)寻找可改进的执行计划
(3)实施能够改进的执行计划以提高SQL效率

2、如何tuning SQL

(1)检查是否为优化器设置了合理的参数(optimizer_mode,optimizer_index_caching,optimizer_index_cost_adj,以及相关cache size)
(2)检查SQL语句所涉及的对象是否存在过时的统计信息或者倾斜列是否缺少直方图等
(3)通过添加提示来引导SQL语句使用正确的访问路径,以及连接方式等
(4)重构等价的SQL语句以使得SQL更高效(如最小化基表及中间结果集,避免列运算,列上的函数,null值,不等运算使得索引失效)
(5)添加合理的索引或物化视图以及移除冗余索引,分散I/O等

3、Automatic Tuning Optimizer 做什么?

(1)分析统计信息

优化器执行计划产生期间记录当前SQL语句涉及对象的统计信息的类型以及哪些被使用或哪些是需要的
当统计信息记录完成后自动调整优化器会比对与查询相关的这些对象的统计信息是否可用或过时或非均衡列缺少直方图等
针对上述的操作之后得到哪些对象没有统计信息以及哪些对象缺少统计信息以及额外的统计信息用于生成report

(2)分析访问路径

优化器会分析当前SQL所使用的访问路径是否合理,也就是分析基于表的访问方式,如全表扫描,索引扫描等
自动调整优化器会基于谓词尝试假设性的推断来创建合理的索引,也就是建议通过添加或修改相应的索引来提高性能

(3)SQL结构分析

优化器会建议对于一些具有较大影响的SQL语句作结构性调整及转换(基于内部规则),如未嵌套的子查询,重写物化视图,视图合并等
基于语法以及语义结构的分析与调整,如谓词列上的运算,UNION与UNION ALL的使用,NOT IN, NOT EXIST之间替换等
对中间结果集以及连接方式等实现一些预估的分析

(4)SQL profiling

SQL profiling 内置于优化器,就是一个剖析工具,基于上述得到的信息对当前的SQL进行剖析,以检查出导致性能糟糕的故障点
所有上述分析得到的结果以及辅助信息最后以sql profile的形式表现出来,供用户来判断是否接受
当用户接受这些profile,下次处于normal模式时,相同的sql语句会使用这个profile
可以对profile进行启用,停用,以及修改,因此即使表发生较大的变化,profile依旧能使得SQL受益

4、Automatic Tuning Optimizer与SQL tuning advisor结构图

5、STA可tuning的方式

STA提供OEM图形界面以及API方式进行tuning,本文主要描述API即dbms_sqltune.create_tuning_task方式,下面是可被create_tuning_task接受的API方式

(1)直接提供SQL语句文本
(2)引用共享池中的SQL语句(sql_id)
(3)引用awr自动工作负载中的SQL语句(sql_id)
(4)建议SQL调优集(批量tuning)

6、演示SQL tuning

(1)环境

scott@ORA11G> select * from v$version where rownum<2;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

(2)创建演示表
scott@ORA11G> CREATE TABLE t
NOLOGGING
3 AS
4 SELECT *
5 FROM dba_source,
6 ( SELECT *
7 FROM DUAL
8 CONNECT BY ROWNUM < 5);
Table created.

(3)执行SQL 语句

scott@ORA11G> SELECT COUNT (*)
2 FROM t a
3 WHERE a.ROWID > (SELECT MIN (b.ROWID)
4 FROM t b
5 WHERE a.owner = b.owner AND a.name = b.name AND a.TYPE = b.TYPE AND a.line = b.line);

COUNT(*)
----------
1872756

1 row selected.

--开始SQL自动调整并报告结果
--脚本tune_last_sql.sql中包含了创建调优任务、开始执行调优、以及报告调优成果。

脚本内容见文章尾部
scott@ORA11G> @tune_last_sql

RECS
-----------------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : TASK_833
Tuning Task Owner : SCOTT
Workload Type : Single SQL Statement
Scope : COMPREHENSIVE
Time Limit(seconds): 1800
Completion Status : COMPLETED
Started at : 05/22/2013 15:06:06
Completed at : 05/22/2013 15:07:17

-------------------------------------------------------------------------------
Schema Name: SCOTT
SQL ID : 44tg722u0ypqh
SQL Text : SELECT COUNT (*)
FROM t a
WHERE a.ROWID > (SELECT MIN (b.ROWID)
FROM t b
WHERE a.owner = b.owner AND a.name = b.name
AND a.TYPE = b.TYPE AND a.line = b.line)

-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------

1- Statistics Finding
---------------------
Table "SCOTT"."T" was not analyzed.

Recommendation
--------------
- Consider collecting optimizer statistics for this table.
execute dbms_stats.gather_table_stats(ownname => 'SCOTT', tabname => 'T',
estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt =>
'FOR ALL COLUMNS SIZE AUTO');

Rationale
---------
The optimizer requires up-to-date statistics for the table in order to
select a good execution plan.

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

1- Original
-----------
Plan hash value: 1985065416

-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 134 | | 42648 (1)| 00:08:32 |
| 1 | SORT AGGREGATE | | 1 | 134 | | | |
|* 2 | HASH JOIN | | 129K| 16M| 195M| 42648 (1)| 00:08:32 |
| 3 | TABLE ACCESS FULL | T | 2590K| 165M| | 11596 (1)| 00:02:20 |
| 4 | VIEW | VW_SQ_1 | 2590K| 165M| | 11674 (1)| 00:02:21 |
| 5 | HASH GROUP BY | | 2590K| 165M| | 11674 (1)| 00:02:21 |
| 6 | TABLE ACCESS FULL| T | 2590K| 165M| | 11596 (1)| 00:02:20 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("A"."OWNER"="ITEM_1" AND "A"."NAME"="ITEM_2" AND
"A"."TYPE"="ITEM_3" AND "A"."LINE"="ITEM_4")
filter("A".ROWID>"MIN(B.ROWID)")

--上面的report总共分为3个部分,分别是SQL调优的基本信息、SQL调优的建议findings、以及SQL对应的执行计划部分
--在基本信息部分包含了SQL调优的任务名称,状态,执行,完成时间,对应的SQL完整语句等
--在finding部分则给出本次调优所得到的成果,如本次是提示缺少统计信息
--在执行计划部分则给出了当前SQL语句的执行计划以及谓词信息

-->接下来根据建议来收集统计信息
scott@ORA11G> BEGIN
2 DBMS_STATS.gather_table_stats (ownname => 'SCOTT',
3 tabname => 'T',
4 estimate_percent => DBMS_STATS.auto_sample_size,
5 method_opt => 'FOR ALL COLUMNS SIZE AUTO');
6 END;
7 /

PL/SQL procedure successfully completed.

-->对原SQL语句增加order提示并执行
scott@ORA11G> SELECT /*+ ordered */COUNT (*)
2 FROM t a
3 WHERE a.ROWID > (SELECT MIN (b.ROWID)
4 FROM t b
5 WHERE a.owner = b.owner AND a.name = b.name AND a.TYPE = b.TYPE AND a.line = b.line);

COUNT(*)
----------
1872756

1 row selected.

--再次调优SQL语句
scott@ORA11G> @tune_last_sql

RECS
-----------------------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : TASK_849
Tuning Task Owner : SCOTT
Workload Type : Single SQL Statement
Scope : COMPREHENSIVE
Time Limit(seconds): 1800
Completion Status : COMPLETED
Started at : 05/22/2013 21:26:07
Completed at : 05/22/2013 21:26:42

-------------------------------------------------------------------------------
Schema Name: SCOTT
SQL ID : fsp3852n56gf8
SQL Text : SELECT /*+ ordered */COUNT (*)
FROM t a
WHERE a.ROWID > (SELECT MIN (b.ROWID) from t b
WHERE a.owner = b.owner AND a.name = b.name AND a.TYPE = b.TYPE
AND a.line = b.line)

-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------

1- SQL Profile Finding (see explain plans section below)
--------------------------------------------------------
A potentially better execution plan was found for this statement.

Recommendation (estimated benefit: 67.95%)
------------------------------------------
- Consider accepting the recommended SQL profile.
execute dbms_sqltune.accept_sql_profile(task_name => 'TASK_849',
task_owner => 'SCOTT', replace => TRUE);

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

1- Original With Adjusted Cost
------------------------------
Plan hash value: 2929971977

--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 218K (1)| 00:43:47 |
| 1 | SORT AGGREGATE | | 1 | | | | |
| 2 | VIEW | VM_NWVW_2 | 551K| | | 218K (1)| 00:43:47 |
|* 3 | FILTER | | | | | | |
| 4 | HASH GROUP BY | | 551K| 51M| 1197M| 218K (1)| 00:43:47 |
|* 5 | HASH JOIN | | 11M| 1031M| 145M| 37646 (1)| 00:07:32 |
| 6 | TABLE ACCESS FULL| T | 2497K| 116M| | 11596 (1)| 00:02:20 |
| 7 | TABLE ACCESS FULL| T | 2497K| 116M| | 11596 (1)| 00:02:20 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter("A".ROWID>MIN("B".ROWID))
5 - access("A"."OWNER"="B"."OWNER" AND "A"."NAME"="B"."NAME" AND
"A"."TYPE"="B"."TYPE" AND "A"."LINE"="B"."LINE")

2- Using SQL Profile
--------------------
Plan hash value: 1985065416

-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 116 | | 70117 (1)| 00:14:02 |
| 1 | SORT AGGREGATE | | 1 | 116 | | | |
|* 2 | HASH JOIN | | 2025K| 224M| 145M| 70117 (1)| 00:14:02 |
| 3 | TABLE ACCESS FULL | T | 2497K| 116M| | 11596 (1)| 00:02:20 |
| 4 | VIEW | VW_SQ_1 | 2497K| 159M| | 41851 (1)| 00:08:23 |
| 5 | HASH GROUP BY | | 2497K| 116M| 153M| 41851 (1)| 00:08:23 |
| 6 | TABLE ACCESS FULL| T | 2497K| 116M| | 11596 (1)| 00:02:20 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("A"."OWNER"="ITEM_1" AND "A"."NAME"="ITEM_2" AND
"A"."TYPE"="ITEM_3" AND "A"."LINE"="ITEM_4")
filter("A".ROWID>"MIN(B.ROWID)")

-------------------------------------------------------------------------------

--针对上述的SQL语句,SQL调优器找到了一个更为高效的执行计划,并提示我们接受该执行计划,如下
--A potentially better execution plan was found for this statement.
--Recommendation (estimated benefit: 67.95%)
--Consider accepting the recommended SQL profile

--Author : Robinson
--Blog : http://blog.csdn.net/robinson_0612

--接受SQL profile
scott@ORA11G> exec DBMS_SQLTUNE.accept_sql_profile (task_name => 'TASK_849', task_owner => 'SCOTT', REPLACE => TRUE);

PL/SQL procedure successfully completed.

--当接受SQL profile后,我们再次来执行原来带order提示的SQL语句
scott@ORA11G> set autot trace exp;
scott@ORA11G> SELECT /*+ ordered */COUNT (*)
2 FROM t a
3 WHERE a.ROWID > (SELECT MIN (b.ROWID) from t b
4 WHERE a.owner = b.owner AND a.name = b.name AND a.TYPE = b.TYPE
5 AND a.line = b.line);

Execution Plan
----------------------------------------------------------
Plan hash value: 1985065416

-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 116 | | 70117 (1)| 00:14:02 |
| 1 | SORT AGGREGATE | | 1 | 116 | | | |
|* 2 | HASH JOIN | | 2025K| 224M| 145M| 70117 (1)| 00:14:02 |
| 3 | TABLE ACCESS FULL | T | 2497K| 116M| | 11596 (1)| 00:02:20 |
| 4 | VIEW | VW_SQ_1 | 2497K| 159M| | 41851 (1)| 00:08:23 |
| 5 | HASH GROUP BY | | 2497K| 116M| 153M| 41851 (1)| 00:08:23 |
| 6 | TABLE ACCESS FULL| T | 2497K| 116M| | 11596 (1)| 00:02:20 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("A"."OWNER"="ITEM_1" AND "A"."NAME"="ITEM_2" AND
"A"."TYPE"="ITEM_3" AND "A"."LINE"="ITEM_4")
filter("A".ROWID>"MIN(B.ROWID)")

Note
-----
- SQL profile "SYS_SQLPROF_013ecc70b5f70000" used for this statement

scott@ORA11G> set autot off;

--上面的autotrace中,最后一部分表明当前的SQL语句使用了存储的SQL profile的执行计划

7、相关视图
DBA_ADVISOR_LOG
DBA_ADVISOR_TASKS
DBA_ADVISOR_FINDINGS
DBA_ADVISOR_RECOMMENDATIONS
DBA_ADVISOR_RATIONALE
DBA_SQLTUNE_STATISTICS
DBA_SQLTUNE_BINDS
DBA_SQLTUNE_PLANS

8、演示用到的脚本

SET ECHO OFF TERMOUT ON FEEDBACK OFF VERIFY OFF
SET SCAN ON
SET LONG 1000000 LINESIZE 180
COL recs FORMAT a135

VARIABLE tuning_task VARCHAR2(30)

DECLARE
l_sql_id v$session.prev_sql_id%TYPE;
BEGIN
SELECT prev_sql_id INTO l_sql_id
FROM v$session
WHERE audsid = userenv('SESSIONID');

:tuning_task := dbms_sqltune.create_tuning_task(sql_id => l_sql_id);
dbms_sqltune.execute_tuning_task(:tuning_task);
END;
/

SELECT dbms_sqltune.report_tuning_task(:tuning_task) as recs
FROM dual;

SET VERIFY ON FEEDBACK ON

更多参考

DML Error Logging 特性

PL/SQL --> 游标

PL/SQL --> 隐式游标(SQL%FOUND)

批量SQL之 FORALL 语句

批量SQL之 BULK COLLECT 子句

PL/SQL 集合的初始化与赋值

PL/SQL 联合数组与嵌套表
PL/SQL 变长数组
PL/SQL --> PL/SQL记录

SQL tuning 步骤

高效SQL语句必杀技

父游标、子游标及共享游标

绑定变量及其优缺点

dbms_xplan之display_cursor函数的使用

dbms_xplan之display函数的使用

执行计划中各字段各模块描述

使用 EXPLAIN PLAN 获取SQL语句执行计划
————————————————
版权声明:本文为CSDN博主「Leshami」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/leshami/article/details/8996253

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2022年1月20日

admin

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

COPYRIGHT © 2022 拓扑园. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

鲁ICP备2021020523号

鲁ICP备2021020523号