Oracle SQLTUNING优化SQL

在这里插入图片描述
通过AWR的TOPSQL观察到sqlid为6pk9xfmjd0s8j的sql语句耗时1分钟。
在这里插入图片描述
在这里插入图片描述
通过ash观察到,该SQL由于全表扫描占用了大量的IO资源。
在这里插入图片描述
解析执行计划,看到是MED_SALE_ORDER表做了全表扫描。
在这里插入图片描述
该表有678W+条记录,全表扫描必定IO指标会冲高,影响数据库性能。

在不了解业务逻辑的情况下,可以通过Oracle的SQL TUNING工具对该SQL进行优化。

declare
 l_tuning_task varchar2(30);
begin
 l_tuning_task := dbms_sqltune.create_tuning_task(sql_id => '6pk9xfmjd0s8j');
 dbms_sqltune.execute_tuning_task(l_tuning_task);
 dbms_output.put_line(l_tuning_task);
end;
/

创建优化任务,可以通过DBA_ADVISOR_LOG查看任务名称。

col owner for a15
col execution_start for a25
col execution_end for a25
set linesize 200
select owner,task_id,task_name,to_char(execution_start,'yyyy-mm-dd hh24:mi:ss') execution_start,to_char(execution_end,'yyyy-mm-dd hh24:mi:ss') execution_end from dba_advisor_log order by 3;

此次优化过程中,优化任务名称查询出来是TASK_97635。
任务创建完成后,执行优化任务。

BEGIN
  DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => 'TASK_97635' );
END;
/

通过DBA_ADVISOR_TASKS视图查看任务执行状态,当状态为COMPLETED表示任务执行完成,可以输出优化报告了。

SELECT status 
FROM   DBA_ADVISOR_TASKS 
WHERE  task_name = 'TASK_97635' ;

输出优化报告

SET LONG 10000 
SET LONGCHUNKSIZE 1000
SET LINESIZE 100      
SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635' )
FROM   DUAL;

以下是优化报告内容:

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name   : TASK_97635
Tuning Task Owner  : SYS
Workload Type      : Single SQL Statement
Execution Count    : 2
Current Execution  : EXEC_100531
Execution Type     : TUNE SQL
Scope              : COMPREHENSIVE
Time Limit(seconds): 1800
Completion Status  : COMPLETED

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
Started at         : 05/22/2023 17:55:04
Completed at       : 05/22/2023 18:00:47

-------------------------------------------------------------------------------
Schema Name: ZTCX
SQL ID     : 6pk9xfmjd0s8j
SQL Text   :

...

2- Index Finding (see explain plans section below)
--------------------------------------------------
  The execution plan of this statement can be improved by creating one or more
  indices.

  Recommendation (estimated benefit: 99.99%)
  ------------------------------------------

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
  - Consider running the Access Advisor to improve the physical schema design
    or creating the recommended index.
    create index OCC_B2B.IDX$$_17D630001 on
    OCC_B2B.MED_SALE_ORDER(TO_NUMBER("PLATFORM_ID"),"ORGANIZATION_ID","DR","TS"
    );

  Rationale
  ---------
    Creating the recommended indices significantly improves the execution plan
    of this statement. However, it might be preferable to run "Access Advisor"
    using a representative SQL workload as opposed to a single statement. This

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
    will allow to get comprehensive index recommendations which takes into
    account index maintenance overhead and additional space consumption.

3- Alternative Plan Finding
---------------------------
  Some alternative execution plans for this statement were found by searching
  the system's real-time and historical performance data.

  The following table lists these plans ranked by their average elapsed time.
  See section "ALTERNATIVE PLANS SECTION" for detailed information on each
  plan.

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------

  id plan hash  last seen            elapsed (s)  origin          note
  -- ---------- -------------------- ------------ --------------- ----------------
   1 1648087086  2023-05-22/15:00:59       13.422 AWR
   2 1676945439  2023-05-22/16:45:01       28.123 Cursor Cache    original plan

  Recommendation
  --------------
  - Consider creating a SQL plan baseline for the plan with the best average
    elapsed time.
    execute dbms_sqltune.create_sql_plan_baseline(task_name => 'TASK_97635',

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
            owner_name => 'SYS', plan_hash_value => 1648087086);

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

1- Original
-----------
Plan hash value: 1676945439

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

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
----------
| Id  | Operation                         | Name                     | Rows  | Bytes | Cost (%CPU)|
Time     |
----------------------------------------------------------------------------------------------------
----------
|   0 | SELECT STATEMENT                  |                          |     1 |   328 |   174K  (1)|
00:34:51 |
|   1 |  HASH UNIQUE                      |                          |     1 |   328 |   174K  (1)|
00:34:51 |
|*  2 |   FILTER                          |                          |       |       |            |
         |

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
|   3 |    NESTED LOOPS                   |                          |     1 |   328 |   174K  (1)|
00:34:51 |
|   4 |     NESTED LOOPS                  |                          |     1 |   328 |   174K  (1)|
00:34:51 |
|   5 |      NESTED LOOPS                 |                          |     1 |   267 |   174K  (1)|
00:34:51 |
|   6 |       NESTED LOOPS                |                          |     1 |   204 |   174K  (1)|
00:34:51 |
|*  7 |        TABLE ACCESS FULL          | MED_SALE_ORDER           |     1 |   117 |   174K  (1)|
00:34:51 |
|*  8 |        TABLE ACCESS BY INDEX ROWID| MED_SALE_ORDER_ITEM      |     2 |   174 |     4   (0)|

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
00:00:01 |
|*  9 |         INDEX RANGE SCAN          | FK_SALE_ORDER__ITEM_H_ID |     3 |       |     2   (0)|
00:00:01 |
|* 10 |       TABLE ACCESS BY INDEX ROWID | MED_OUTER_ORDER_ITEM     |     1 |    63 |     3   (0)|
00:00:01 |
|* 11 |        INDEX RANGE SCAN           | I_MED_SRC_ORDER_ITEM_ID  |     1 |       |     2   (0)|
00:00:01 |
|* 12 |      INDEX UNIQUE SCAN            | I_ID                     |     1 |       |     1   (0)|
00:00:01 |
|* 13 |     TABLE ACCESS BY INDEX ROWID   | MED_OUTER_ORDER          |     1 |    61 |     2   (0)|
00:00:01 |

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
----------

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

   2 - filter(SYSDATE@!>=SYSDATE@!-:SYS_B_5/:SYS_B_6)
   7 - filter("B"."ORGANIZATION_ID"=:1 AND TO_NUMBER("B"."PLATFORM_ID")=:SYS_B_4 AND
              "B"."DR"=:SYS_B_1 AND "B"."TS"<=SYSDATE@! AND "B"."TS">=SYSDATE@!-:SYS_B_5/:SYS_B_6)
   8 - filter("A"."SRC_ROWID" IS NOT NULL AND "A"."DR"=:SYS_B_0)
   9 - access("A"."SALEORDER_ID"="B"."ID")

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
  10 - filter("C"."DR"=:SYS_B_2)
  11 - access("A"."SRC_ROWID"="C"."SRC_ORDER_ITEM_ID")
  12 - access("C"."OUTER_ORDER_ID"="D"."ID")
  13 - filter("D"."DR"=:SYS_B_3 AND ("B"."CUSTOMER_ID"<>"D"."CUSTOMER_ID" OR
              "A"."OUTER_ORDER_ID"<>"D"."ID"))

2- Using New Indices
--------------------
Plan hash value: 4060887534

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

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
----------
| Id  | Operation                         | Name                     | Rows  | Bytes | Cost (%CPU)|
Time     |
----------------------------------------------------------------------------------------------------
----------
|   0 | SELECT STATEMENT                  |                          |     1 |   328 |    15   (7)|
00:00:01 |
|   1 |  HASH UNIQUE                      |                          |     1 |   328 |    15   (7)|
00:00:01 |
|*  2 |   FILTER                          |                          |       |       |            |
         |

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
|   3 |    NESTED LOOPS                   |                          |     1 |   328 |    14   (0)|
00:00:01 |
|   4 |     NESTED LOOPS                  |                          |     1 |   328 |    14   (0)|
00:00:01 |
|   5 |      NESTED LOOPS                 |                          |     1 |   267 |    12   (0)|
00:00:01 |
|   6 |       NESTED LOOPS                |                          |     1 |   204 |     9   (0)|
00:00:01 |
|   7 |        TABLE ACCESS BY INDEX ROWID| MED_SALE_ORDER           |     1 |   117 |     5   (0)|
00:00:01 |
|*  8 |         INDEX RANGE SCAN          | IDX$$_17D630001          |     1 |       |     4   (0)|

DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_97635')
----------------------------------------------------------------------------------------------------
00:00:01 |
|*  9 |        TABLE ACCESS BY INDEX ROWID| MED_SALE_ORDER_ITEM      |     2 |   174 |     4   (0)|
00:00:01 |
|* 10 |         INDEX RANGE SCAN

从优化输出报告中看出,需要创建索引:
create index OCC_B2B.IDX$$_17D630001 on OCC_B2B.MED_SALE_ORDER(TO_NUMBER(“PLATFORM_ID”),“ORGANIZATION_ID”,“DR”,“TS”
);

创建索引后新给的执行计划规避了全表扫描,性能也有极大的提升
在这里插入图片描述
在这里插入图片描述
将该优化建议提交给业务部门,让其在开发测试环境先做充分测试,若切实有效再上生产

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle SQL优化是指通过调整SQL查询语句和数据库结构,以提高查询性能和响应时间的过程。下面是一些常用的Oracle SQL优化技巧: 1. 使用合适的索引:确保表中的列上有适当的索引,以加快查询速度。可以使用EXPLAIN PLAN或者SQL Tuning Advisor来分析查询计划,并建议适当的索引。 2. 编写高效的查询语句:尽量避免使用SELECT *,只选择需要的列;使用合适的JOIN语句,避免不必要的连接;使用WHERE子句限制返回的行数。 3. 使用合适的数据类型:选择合适的数据类型可以减少存储空间和加速查询。例如,使用整数类型代替字符类型存储数字数据。 4. 避免使用函数和表达式:在WHERE子句中使用函数或表达式会导致索引失效,影响查询性能。尽量将函数和表达式移到SELECT列表之外。 5. 分析统计信息:确保收集和更新表和索引的统计信息,以便优化查询计划的生成。可以使用DBMS_STATS包来收集统计信息。 6. 优化连接操作:对于复杂的连接操作,可以考虑使用合适的连接方式(如HASH JOIN、NESTED LOOP等),以及使用连接池和缓存来提高性能。 7. 使用分区表:对于大型表,可以考虑使用分区表来提高查询性能。分区可以根据特定的列值将数据划分为更小的块,使查询更加高效。 8. 避免全表扫描:尽量避免全表扫描操作,可以通过合理使用索引、分区表等技术来避免全表扫描,以提高查询性能。 9. 使用Hint提示:可以使用查询提示(Hint)来指导优化器生成最优的执行计划。但是需要谨慎使用,因为错误的Hint可能导致性能下降。 10. 监视和调整数据库参数:根据实际情况,监视和调整数据库参数,以优化整体数据库性能。 综上所述,Oracle SQL优化需要综合考虑查询语句、索引、表结构、统计信息等多个方面的因素。通过合理的优化策略,可以提高查询性能和响应时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值