ITPub博客

首页 > Linux操作系统 > Linux操作系统 > sql profile

sql profile

原创 Linux操作系统 作者:is.x 时间:2011-11-24 00:42:40 0 删除 编辑

记录一下最近在生产上应用的sql profile使用方法:

 

首先建立测试表:

 

SQL> select * from v$version;

 

BANNER

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

Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod

PL/SQL Release 10.2.0.3.0 - Production

CORE    10.2.0.3.0      Production

TNS for Solaris: Version 10.2.0.3.0 - Production

NLSRTL Version 10.2.0.3.0 - Production

 

SQL>

SQL> create table t as select * from dba_objects;

 

Table created.

 

SQL> create index t_idx on t(object_id);

 

Index created.

 

SQL> exec dbms_stats.gather_table_stats('TEST','T',cascade=>true);  

 

PL/SQL procedure successfully completed.

 

假设我现在需要调优的sql语句是select object_id,object_name from t where object_id=:a;

 

先看一下默认情况下,此语句的执行计划和outline:

 

SQL> set linesize 300 pagesize 300

SQL> explain plan for select object_id,object_name from t where object_id=:a;

 

Explained.

 

SQL> select * from table(dbms_xplan.display(null,null,'outline'));

 

PLAN_TABLE_OUTPUT

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

Plan hash value: 470836197

 

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

| Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0 | SELECT STATEMENT            |       |     1 |    23 |     2   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| T     |     1 |    23 |     2   (0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | T_IDX |     1 |       |     1   (0)| 00:00:01 |

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

 

Outline Data

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

 

  /*+

      BEGIN_OUTLINE_DATA

      INDEX_RS_ASC(@"SEL$1" "T"@"SEL$1" ("T"."OBJECT_ID"))

      OUTLINE_LEAF(@"SEL$1")

      ALL_ROWS

      OPTIMIZER_FEATURES_ENABLE('10.2.0.3')

      IGNORE_OPTIM_EMBEDDED_HINTS

      END_OUTLINE_DATA

  */

 

Predicate Information (identified by operation id):

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

 

   2 - access("OBJECT_ID"=TO_NUMBER(:A))

 

27 rows selected.

 

其使用了INDEX RANGE SCAN,现在增加hint,强制sql语句全表扫描。

 

SQL> explain plan for select /*+ full(t) */ object_id,object_name from t where object_id=:a;

 

Explained.

 

SQL> select * from table(dbms_xplan.display(null,null,'outline'));

 

PLAN_TABLE_OUTPUT

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

Plan hash value: 1601196873

 

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

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0 | SELECT STATEMENT  |      |     1 |    23 |    34   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| T    |     1 |    23 |    34   (0)| 00:00:01 |

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

 

Outline Data

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

 

  /*+

      BEGIN_OUTLINE_DATA

      FULL(@"SEL$1" "T"@"SEL$1")

      OUTLINE_LEAF(@"SEL$1")

      ALL_ROWS

      OPTIMIZER_FEATURES_ENABLE('10.2.0.3')

      IGNORE_OPTIM_EMBEDDED_HINTS

      END_OUTLINE_DATA

  */

 

Predicate Information (identified by operation id):

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

 

   1 - filter("OBJECT_ID"=TO_NUMBER(:A))

 

26 rows selected.

 

好了,对比一下outline data部分。原来的INDEX RANGE SCAN:

  /*+

      BEGIN_OUTLINE_DATA

      INDEX_RS_ASC(@"SEL$1" "T"@"SEL$1" ("T"."OBJECT_ID"))

      OUTLINE_LEAF(@"SEL$1")

      ALL_ROWS

      OPTIMIZER_FEATURES_ENABLE('10.2.0.3')

      IGNORE_OPTIM_EMBEDDED_HINTS

      END_OUTLINE_DATA

  */

 

现在的TABLE ACCESS FULL:

  /*+

      BEGIN_OUTLINE_DATA

      FULL(@"SEL$1" "T"@"SEL$1")

      OUTLINE_LEAF(@"SEL$1")

      ALL_ROWS

      OPTIMIZER_FEATURES_ENABLE('10.2.0.3')

      IGNORE_OPTIM_EMBEDDED_HINTS

      END_OUTLINE_DATA

  */

 

如果期望调优的sql语句select object_id,object_name from t where object_id=:a;使用全表扫描,那么可以使用sql profile来固化执行计划。

 

SQL> conn / as sysdba

Connected.

SQL> declare

  2     v_hints sys.sqlprof_attr;

  3  begin

  4     v_hints := sys.sqlprof_attr('FULL(@"SEL$1" "T"@"SEL$1")');

  5     dbms_sqltune.import_sql_profile('select object_id,object_name from t where object_id=:a',

  6                                    v_hints,

  7                                    'SQLPROFILE_TEST',

  8                                    force_match => true);

  9  end;

 10  /

 

PL/SQL procedure successfully completed.

 

这里的sys.sqlprof_attr('FULL(@"SEL$1" "T"@"SEL$1")')从对应的outline中提取。

 

好了,看看sql profile创建后的sql语句执行计划:

SQL> conn test/test

Connected.

SQL> explain plan for select object_id,object_name from t where object_id=:a;

 

Explained.

 

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

 

PLAN_TABLE_OUTPUT

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

Plan hash value: 1601196873

 

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

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0 | SELECT STATEMENT  |      |     1 |    23 |    34   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| T    |     1 |    23 |    34   (0)| 00:00:01 |

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

 

Predicate Information (identified by operation id):

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

 

   1 - filter("OBJECT_ID"=TO_NUMBER(:A))

 

Note

-----

   - SQL profile "SQLPROFILE_TEST" used for this statement

 

17 rows selected.

 

SQL> explain plan for select /*+ full(t) */ object_id,object_name from t where object_id=:a;

 

Explained.

 

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

 

PLAN_TABLE_OUTPUT

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

Plan hash value: 1601196873

 

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

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0 | SELECT STATEMENT  |      |     1 |    23 |    34   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| T    |     1 |    23 |    34   (0)| 00:00:01 |

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

 

Predicate Information (identified by operation id):

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

 

   1 - filter("OBJECT_ID"=TO_NUMBER(:A))

 

13 rows selected.

 

sql语句按照我们的意愿进行了全表扫描。

 

如果想删除sql profile,可以使用以下方法:

 

SQL> conn / as sysdba

Connected.

SQL> exec dbms_sqltune.drop_sql_profile('SQLPROFILE_TEST');

 

PL/SQL procedure successfully completed.

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/20750200/viewspace-711882/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: ORA-600 [17070] 报错
下一篇: dba_dependencies
请登录后发表评论 登录
全部评论

注册时间:2011-04-27

  • 博文量
    73
  • 访问量
    294004