暂无图片
暂无图片
3
暂无图片
暂无图片
暂无图片

使用sql_profile替换执行计划

原创 _ 云和恩墨 2023-02-01
1056

一、准备数据

SQL> select deptno,count(*) from t2 group by deptno;

    DEPTNO   COUNT(*)
---------- ----------
        40          1
        30          1
        10     524289
        20     524289
		
SQL> create index t1 on t2(deptno);

Index created.

SQL> exec dbms_stats.gather_table_stats('SYS','t2',method_opt=>'for all columns  size auto');

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_table_stats('SYS','t2',method_opt=>'for   columns DEPTNO  size skewonly');

PL/SQL procedure successfully completed.

二、测试sql执行计划

SQL> set linesize 150

SQL> alter session set cursor_sharing=force;

Session altered.

SQL> select count(*) from t2 where deptno=40;

  COUNT(*)
----------
         1

SQL> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  bt33t77y2w9mf, child number 0
-------------------------------------
select count(*) from t2 where deptno=:"SYS_B_0"

Plan hash value: 3441024023

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       |     3 (100)|          |
|   1 |  SORT AGGREGATE   |      |     1 |     3 |            |          |
|*  2 |   INDEX RANGE SCAN| T1   |     1 |     3 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

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

   2 - access("DEPTNO"=:SYS_B_0)


19 rows selected.

三、将该执行计划创建基线

SQL> SQL> declare 
  2  rs pls_integer;
  3  begin
  4  rs:=dbms_spm.load_plans_from_cursor_cache('bt33t77y2w9mf');
  5  end;
  6  /

PL/SQL procedure successfully completed.
SQL> select sql_handle,plan_name,substr(sql_text,1,30) sql_text,accepted from dba_sql_plan_baselines where enabled='YES';

SQL_HANDLE                     PLAN_NAME                      SQL_TEXT                       ACCEPT
------------------------------ ------------------------------ ------------------------------ ------
SQL_a32e7f05dacde247           SQL_PLAN_a6bmz0rdcvsk7ecfa9855 select count(*) from t2 where  YES

--3、测试新sql

SQL> select count(*) from t2 where deptno=10;

  COUNT(*)
----------
    524289

SQL> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  bt33t77y2w9mf, child number 1

An uncaught error happened in prepare_sql_statement : ORA-01403: no data found

NOTE: cannot fetch plan for SQL_ID: bt33t77y2w9mf, CHILD_NUMBER: 1
      Please verify value of SQL_ID and CHILD_NUMBER;
      It could also be that the plan is no longer in cursor cache (check v$sql_plan)


8 rows selected.

SQL> select count(*) from t2 where deptno=10;

  COUNT(*)
----------
    524289

SQL> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  bt33t77y2w9mf, child number 1
-------------------------------------
select count(*) from t2 where deptno=:"SYS_B_0"

Plan hash value: 3441024023

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       |  1030 (100)|          |
|   1 |  SORT AGGREGATE   |      |     1 |     3 |            |          |
|*  2 |   INDEX RANGE SCAN| T1   |   524K|  1536K|  1030   (1)| 00:00:01 |
--------------------------------------------------------------------------

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

   2 - access("DEPTNO"=:SYS_B_0)

Note
-----
   - SQL plan baseline SQL_PLAN_a6bmz0rdcvsk7ecfa9855 used for this statement


23 rows selected.

此处应该走全表,所以执行计划是错误的。

四、使用hint走全表

SQL> select /*+ full(t2) */ count(*) from t2 where deptno=10;

  COUNT(*)
----------
    524289

SQL> select * from table(dbms_xplan.display_cursor);


PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  8uvxtbn283qwz, child number 0
-------------------------------------
select /*+ full(t2) */ count(*) from t2 where deptno=:"SYS_B_0"

Plan hash value: 3321871023

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |  1105 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     3 |            |          |
|*  2 |   TABLE ACCESS FULL| T2   |   524K|  1536K|  1105   (1)| 00:00:01 |
---------------------------------------------------------------------------

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

   2 - filter("DEPTNO"=:SYS_B_0)


19 rows selected.

五、将该sql加载进baseline

SQL> SQL> declare 
  2  rs pls_integer;
  3  begin
  4  rs:=dbms_spm.load_plans_from_cursor_cache('8uvxtbn283qwz');
  5  end;
  6  /

PL/SQL procedure successfully completed.

SQL> select sql_handle,plan_name,substr(sql_text,1,30) sql_text,accepted from dba_sql_plan_baselines where enabled='YES';

SQL_HANDLE                     PLAN_NAME                      SQL_TEXT                       ACCEPT
------------------------------ ------------------------------ ------------------------------ ------
SQL_859a43fd4bfd0a47           SQL_PLAN_8b6k3zp5zu2k71c6cf506 select /*+ full(t2) */ count(* YES
SQL_a32e7f05dacde247           SQL_PLAN_a6bmz0rdcvsk7c07ed1b4 select count(*) from t2 where  NO
SQL_a32e7f05dacde247           SQL_PLAN_a6bmz0rdcvsk7ecfa9855 select count(*) from t2 where  YES

六、用带hint提示的执行计划代替索引快速全扫描(连接基线)

6.1、停用原基线
SQL> declare 
  2   rs pls_integer;
  3   begin
  4     rs:=DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
  5     plan_name=>'SQL_PLAN_a6bmz0rdcvsk7ecfa9855',
  6     attribute_name=>'ENABLED',
  7     attribute_value=>'NO');
  8  end;
  9  /

PL/SQL procedure successfully completed.

6.2、连接新基线

SQL>   declare 
  2      ln_ps pls_integer;
  3   begin
  4      ln_ps:=dbms_spm.load_plans_from_cursor_cache
  5      (sql_id=>'8uvxtbn283qwz',                    --带hint的sql
  6      plan_hash_value=>3321871023,
  7      sql_handle=>'SQL_a32e7f05dacde247'           --不带hint的sql_handle
  8      );
  9   end;
 10   /

PL/SQL procedure successfully completed.

SQL> select count(*) from t2 where deptno=10;

  COUNT(*)
----------
    524289

SQL> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  bt33t77y2w9mf, child number 1
-------------------------------------
select count(*) from t2 where deptno=:"SYS_B_0"

Plan hash value: 3321871023

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |       |       |  1105 (100)|          |
|   1 |  SORT AGGREGATE    |      |     1 |     3 |            |          |
|*  2 |   TABLE ACCESS FULL| T2   |   524K|  1536K|  1105   (1)| 00:00:01 |
---------------------------------------------------------------------------

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

   2 - filter("DEPTNO"=:SYS_B_0)

Note
-----
   - SQL plan baseline SQL_PLAN_a6bmz0rdcvsk71c6cf506 used for this statement


23 rows selected.
最后修改时间:2023-03-02 14:55:34
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论