热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

查看执行计划的常用办法(一)

看执行计划的方法很多,例如有setautotrace、dbms_xplan、10046、10053等,而最真实的反应执行计划的只有10046event,这个后面小鱼会列举出部分的案例来反应这个情况,这里我们主要针对上述几个查看执行计划的方法进行一点剖析1setautotraceSetautotr

看执行计划的方法很多,例如有set autotrace、dbms_xplan、10046、10053等,而最真实的反应执行计划的只有10046 event,这个后面小鱼会列举出部分的案例来反应这个情况,这里我们主要针对上述几个查看执行计划的方法进行一点剖析 1 set autotrace Set autotr

看执行计划的方法很多,例如有set autotrace、dbms_xplan、10046、10053等,而最真实的反应执行计划的只有10046 event,这个后面小鱼会列举出部分的案例来反应这个情况,这里我们主要针对上述几个查看执行计划的方法进行一点剖析

1 set autotrace
Set autotrace这个可以查看执行计划和执行sql消耗的统计信息。
SQL> set autotrace traceoly
SQL> select * from t01 where object_id between 19900 and 20000;

101 rows selected.

Execution Plan
----------------------------------------------------------
Plan hash value: 253365841

--------------------------------------------------------------------------------
----------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
Time |
--------------------------------------------------------------------------------
----------
| 0 | SELECT STATEMENT | | 99 | 9207 | 4 (0)|
00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T01 | 99 | 9207 | 4 (0)|
00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T01_ID | 99 | | 2 (0)|
00:00:01 |
--------------------------------------------------------------------------------
----------

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

2 - access("OBJECT_ID">=19900 AND "OBJECT_ID"<=20000)

Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
20 consistent gets
0 physical reads
0 redo size
6498 bytes sent via SQL*Net to client
558 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
101 rows processed

除了显示执行计划外还显示了sql语句执行过程消耗的资源,具体的autotrace使用办法都是比较简单,可以参考官档的详细说明,这个就不再叙述。

Autotrace 其实转化为了两个sql语句,其中一个是这个session的执行sql语句,另一个是explain plan for statement_id=’’ for 原sql语句,我们来进行验证下
Session A:
SQL> alter system flush shared_pool;

System altered.

SQL> select * from t01;

50079 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3295674804

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 50079 | 4548K| 159 (2)| 00:00:02 |
| 1 | TABLE ACCESS FULL| T01 | 50079 | 4548K| 159 (2)| 00:00:02 |
--------------------------------------------------------------------------

Statistics
----------------------------------------------------------
1229 recursive calls
0 db block gets
4183 consistent gets
0 physical reads
0 redo size
2569820 bytes sent via SQL*Net to client
37210 bytes received via SQL*Net from client
3340 SQL*Net roundtrips to/from client
12 sorts (memory)
0 sorts (disk)
50079 rows processed

Session B:
SQL> select sql_id,sql_text from v$sql where sql_text like '%select * from t01%'
and sql_text not like '%v$sql%';

SQL_ID
-------------
SQL_TEXT
--------------------------------------------------------------------------------

5ts7a9dr622qv
select * from t01

ft6jyj0gxkkvs
EXPLAIN PLAN SET STATEMENT_ID='PLUS190008' FOR select * from t01

还有一个需要注意的地方是 set autotrace traceonly exp下,select的sql是不会执行的,只是进行解析,而如果是dml的sql语句,则除了解析还是实际执行,请看下面的示例:
SQL> alter system flush shared_pool;
SQL> set autotrace traceonly exp
SQL> select * from t01;

Execution Plan
----------------------------------------------------------
Plan hash value: 3295674804

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 50079 | 4548K| 159 (2)| 00:00:02 |
| 1 | TABLE ACCESS FULL| T01 | 50079 | 4548K| 159 (2)| 00:00:02 |
--------------------------------------------------------------------------

查看v$sql中发现这个sql语句只是进行解析,并没有实际执行
SQL> select sql_id,sql_text,parse_calls,executions,fetches from v$sql where sql_
text like 'select * from t01%';

SQL_ID SQL_TEXT PARSE_CALLS EXECUTIONS FETCHES
------------- -------------------- ----------- ---------- ----------
5ts7a9dr622qv select * from t01 1 0 0

而如果是dml语句,则不仅会解析这个sql语句还会执行:
SQL> set autotrace traceonly exp
SQL> delete from t01 where rownum<10;

9 rows deleted.

Execution Plan
----------------------------------------------------------
Plan hash value: 3885504243

----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 9 | 63 | 158 (1)| 00:00:02 |
| 1 | DELETE | T01 | | | | |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | TABLE ACCESS FULL| T01 | 50079 | 342K| 158 (1)| 00:00:02 |
----------------------------------------------------------------------------

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

2 - filter(ROWNUM<10)
SQL> select sql_id,sql_text,parse_calls,executions,fetches from v$sql where sql_
text like 'delete from t01 where rownum<10%';

SQL_ID SQL_TEXT PARSE_CALLS EXECUTIONS FETCHES
------------- -------------------- ----------- ---------- ----------
62cp99p4bzkst delete from t01 wher 1 1 0
e rownum<10

2 dbms_xplan
Dbms_xplan包提供了一系列查看执行计划的函数,官档有一个大体的介绍:
The DBMS_XPLAN package supplies five table functions:
? DISPLAY - to format and display the contents of a plan table.
? DISPLAY_AWR - to format and display the contents of the execution plan of a stored SQL statement in the AWR.
? DISPLAY_CURSOR - to format and display the contents of the execution plan of any loaded cursor.
? DISPLAY_SQL_PLAN_BASELINE - to display one or more execution plans for the SQL statement identified by SQL handle
? DISPLAY_SQLSET - to format and display the contents of the execution plan of statements stored in a SQL tuning set.
Display主要用于显示cbo预估的执行计划,此时这个sql不需要真正执行
DBMS_XPLAN.DISPLAY(
table_name IN VARCHAR2 DEFAULT 'PLAN_TABLE',
statement_id IN VARCHAR2 DEFAULT NULL,
format IN VARCHAR2 DEFAULT 'TYPICAL',
filter_preds IN VARCHAR2 DEFAULT NULL);

table_name默认是PLAN_TABLE,这个PLAN_TABLE其实很有意思,我们来对其进行简单的分析

SQL> select object_type from dba_objects where object_name='PLAN_TABLE';

OBJECT_TYPE
-------------------
SYNONYM
SQL> select table_name,owner from dba_synonyms where synonym_name='PLAN_TABLE';

TABLE_NAME OWNER
------------------------------ ------------------------------
PLAN_TABLE$ PUBLIC

PLAN_TABLE其实是PLAN_TABLE$的public synonym,那么来看看PLAN_TABLE$的定义
SQL> select dbms_metadata.get_ddl('TABLE','PLAN_TABLE$','SYS') from dual;

DBMS_METADATA.GET_DDL('TABLE','PLAN_TABLE$','SYS')
--------------------------------------------------------------------------------

CREATE GLOBAL TEMPORARY TABLE "SYS"."PLAN_TABLE$"
( "STATEMENT_ID" VARCHAR2(30),
"PLAN_ID" NUMBER,
"TIMESTAMP" DATE,
"REMARKS" VARCHAR2(4000),
"OPERATION" VARCHAR2(30),
"OPTIONS" VARCHAR2(255),
"OBJECT_NODE" VARCHAR2(128),
"OBJECT_OWNER" VARCHAR2(30),
"OBJECT_NAME" VARCHAR2(30),
"OBJECT_ALIAS" VARCHAR2(65),
"OBJECT_INSTANCE" NUMBER(*,0),
"OBJECT_TYPE" VARCHAR2(30),
"OPTIMIZER" VARCHAR2(255),
"SEARCH_C OLUMNS" NUMBER,
"ID" NUMBER(*,0),
"PARENT_ID" NUMBER(*,0),
"DEPTH" NUMBER(*,0),
"POSITION" NUMBER(*,0),
"COST" NUMBER(*,0),
"CARDINALITY" NUMBER(*,0),
"BYTES" NUMBER(*,0),
"OTHER_TAG" VARCHAR2(255),
"PARTITION_START" VARCHAR2(255),
"PARTITION_STOP" VARCHAR2(255),
"PARTITION_ID" NUMBER(*,0),
"OTHER" LONG,
"OTHER_XML" CLOB,
"DISTRIBUTION" VARCHAR2(30),
"CPU_COST" NUMBER(*,0),
"IO_COST" NUMBER(*,0),
"TEMP_SPACE" NUMBER(*,0),
"ACCESS_PREDICATES" VARCHAR2(4000),
"FILTER_PREDICATES" VARCHAR2(4000),
"PROJECTION" VARCHAR2(4000),
"TIME" NUMBER(*,0),
"QBLOCK_NAME" VARCHAR2(30)
) ON COMMIT PRESERVE ROWS

这个看出plan_table$是个基于session级别的global temporary table,这里我们需要注意的是为什么我们很多会话查询plan_table确没有出现冲突了,其实oracle是这么处理的:
首先建立了plan_table$的session 级别的global temporary table了,然后创建一个public synonym的plan_table指向了临时表plan_table$,最后授予dml和select等权限给这个public synonym plan_table,也就实现了不同用户可以查询同一个表但是数据又不冲突

oracle的$ORACLE_HOME/rdbms/admin/catplan.sql的脚本,该脚本是用来创建临时表plan_table$的,截取部分sql语句如下:
drop table plan_table$;
create global temporary table plan_table$
(
statement_id varchar2(30),
plan_id number,
timestamp date,
remarks varchar2(4000),
operation varchar2(30),
options varchar2(255),
object_node varchar2(128),
object_owner varchar2(30),
object_name varchar2(30),
object_alias varchar2(65),
object_instance numeric,
object_type varchar2(30),
optimizer varchar2(255),
search_columns number,
id numeric,
parent_id numeric,
depth numeric,
position numeric,
cost numeric,
cardinality numeric,
bytes numeric,
other_tag varchar2(255),
partition_start varchar2(255),
partition_stop varchar2(255),
partition_id numeric,
other long,
other_xml clob,
distribution varchar2(30),
cpu_cost numeric,
io_cost numeric,
temp_space numeric,
access_predicates varchar2(4000),
filter_predicates varchar2(4000),
projection varchar2(4000),
time numeric,
qblock_name varchar2(30)
) on commit preserve rows
/
--注意这里需要授权给public同义词,不然别的用户无法做dml操作。
grant select, insert, update, delete on plan_table$ to public
/
create or replace public synonym plan_table for plan_table$
/

小鱼个人觉得这个办法很多应用程序都可以参考使用来实现数据隔离,$ORACLE_HOME/rdbms/admin下的很多脚本都值得细细摸索。

Statement_id为特定需要展示的执行计划的sql语句,默认为null,null表示展示最近执行explain的语句对应的执行计划

Format为展示执行计划的几种方式,oracle官档给出有下列四种:
Basic:displays the minimum information in the plan-the operation ID,the operation name and its option.
Typical : this is the default.Displays the most relevant information in the plan(operation id,name and option,#row,#bytes and optimizer cost).Pruning,parallel and prediace information are only display when applicable.Excludes only PROJECTION,ALIAS and REMOTE SQL information(see below)
SERIAL : Like TYPICAL except that the parallel information is not displayed,event if the plan executes in parallel.
ALL : Maximum user level. Includes information displayed with the TYPICAL level with addition information(PROJECTION,ALIAS and information about REMOTE SQL if the operation is distributed).

其实还有一个小鱼个人经常喜欢用advanced,下面展示下如何用dbms_xplan.display去查看cbo预估的执行计划

SQL> explain plan for select * from t01 where object_name='IND$';

Explained.

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

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
------------------------------------------------------------
Plan hash value: 3295674804

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8 | 1416 | 158 (1)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| T01 | 8 | 1416 | 158 (1)| 00:00:02 |
--------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

1 - SEL$1 / T01@SEL$1

Outline Data
-------------

/*+
BEGIN_OUTLINE_DATA
FULL(@"SEL$1" "T01"@"SEL$1")
OUTLINE_LEAF(@"SEL$1")
ALL_ROWS
OPTIMIZER_FEATURES_ENABLE('10.2.0.4')
IGNORE_OPTIM_EMBEDDED_HINTS
END_OUTLINE_DATA
*/

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

1 - filter("OBJECT_NAME"='IND$')

Column Projection Information (identified by operation id):
-----------------------------------------------------------

1 - "T01"."OWNER"[VARCHAR2,30], "OBJECT_NAME"[VARCHAR2,128],
"T01"."SUBOBJECT_NAME"[VARCHAR2,30], "T01"."OBJECT_ID"[NUMBER,22],
"T01"."DATA_OBJECT_ID"[NUMBER,22], "T01"."OBJECT_TYPE"[VARCHAR2,19],
"T01"."CREATED"[DATE,7], "T01"."LAST_DDL_TIME"[DATE,7],
"T01"."TIMESTAMP"[VARCHAR2,19], "T01"."STATUS"[VARCHAR2,7],
"T01"."TEMPORARY"[VARCHAR2,1], "T01"."GENERATED"[VARCHAR2,1],
"T01"."SECONDARY"[VARCHAR2,1]

Note
-----
- dynamic sampling used for this statement

46 rows selected.

Advanced除了显示了默认参数typical的执行计划和谓词过滤和note信息(如果有动态采样、sql profile、cardinalityfeedback还会有个note的信息),还会显示Query Block Name/object alias、outline data和column projection information。

Advanced展示了outline data,这个可以帮助我们展示一些复杂sql的hint写法。

最近case是因为生产环境10GR2有个列的直方图信息总是被删除导致sql执行计划总是出现了问题,而何种原因造成这个直方图信息被删除一直很难查找,小鱼利用这个advanced展示了这个复杂sql的outline data,这个outline data其实可以也可以当做一个hint的写法,特别对于复杂sql的hint写法基本基本很难完成,当然固化执行计划的方法很多,后面小鱼会专门整理一篇文章来进行分析

下面来看看dbms_xplan.display_awr
Dbms_xplan.display_awr是用来显示保存在awr报告中的执行计划,跟dbms_xplan.display不同点是这个sql是执行过的,并且被保存在awr中。

DBMS_XPLAN.DISPLAY_AWR(
sql_id IN VARCHAR2,
plan_hash_value IN NUMBER DEFAULT NULL,
db_id IN NUMBER DEFAULT NULL,
format IN VARCHAR2 DEFAULT TYPICAL);

sql_id是sql语句的sql_id
plan_hash_value是sql_id相关联的plan_hash_value,如果不指定默认为null,此时展示的这个sql_id对应的所有执行计划
db_id是database db_id
format和dbms_xplan.display中的含义一样,不再详述

需要注意的是同一个sql_id可能有多个执行计划,比如一个父游标可能有多个子游标,一个子游标对应于一个执行计划,而这个执行计划(也就是plan_hash_value)可能相同,也可能不相同,我们往往对比sql_id都是直接查看的sql文本,也就是所说的父游标,父游标是不存储执行计划的,而执行计划则存储在子游标中heap 6中。

业界有个描述父游标、子游标和执行计划的关系:
HASH VALUE101-----------> 父游标Handle
|
Heap0
---------------------------------------------------
| |
子游标1 Handle 子游标2 Handle ………………
|
子游标Heap 0 ----->子游标Heap 6(也就是存储执行计划的地方)

HASH VALUE102 ------->…………

HASH VALUE103 ------->…………
………………………
先来张草图随便看看吧,简单描述一下,父游标Handle中有Heap 0地址,父游标的Heap 0中有它的所有子游标的Handle , 每个子游标的Handle中,又有子游标各自Heap 0的地址,Heap 0中有Heap 6地址,Heap 6就是执行计划。每个Handle、Heap处,都会有Library cache lock/pin 和相关Latch,或者Mutex。而且在硬、软、软软解析时,这些地方的这些锁、Pin、Latch、Mutex都不一样,所以这一块是相当复杂的。

当采样awr报表中发现某个sql语句对系统影响较大时,而现在的shared pool中可能该子游标又已经被踢出shared pool时,此时可以用dbms_xplan.display_awr来查看awr中曾经的执行计划来进行分析
具体使用方法比较简单,不再列出。

继续看看dbms_xplan.display_cursor
Dbms_xplan.display_cursor展示的是存储在shared pool中的执行游标的执行计划。
DBMS_XPLAN.DISPLAY_CURSOR(
sql_id IN VARCHAR2 DEFAULT NULL,
child_number IN NUMBER DEFAULT NULL,
format IN VARCHAR2 DEFAULT 'TYPICAL');

这里有个新的参数是child_number,这个表示的子游标的编号,上面小鱼就说过一个父游标可能对应多个子游标,子游标存储具体的执行计划,子游标都有其各自的child_number,这个可以查询v$sql视图来看看具体的某个父游标sql_id有多少个child_number

Sql_id如果不声明,默认展示最近的sql执行计划,child_number默认为0,设置null则展示该sql_id所有的子游标执行计划。

Format跟上面两个函数有一些变化,多了iostats、memstats、allstats参数
SQL> select /*+gather_plan_statistics*/* from t01 where object_id=1;

no rows selected

SQL> select * from table(dbms_xplan.display_cursor(null,null,'advanced allstats
last'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
------------------------------------------------------------
SQL_ID 9fxrn9aygh837, child number 0
-------------------------------------
select /*+gather_plan_statistics*/* from t01 where object_id=1

Plan hash value: 253365841

--------------------------------------------------------------------------------
----------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cos
t (%CPU)| E-Time | A-Rows | A-Time | Buffers |
--------------------------------------------------------------------------------
----------------------------------------------------
| 1 | TABLE ACCESS BY INDEX ROWID| T01 | 1 | 1 | 93 |
2 (0)| 00:00:01 | 0 |00:00:00.01 | 2 |
|* 2 | INDEX RANGE SCAN | IND_T01_ID | 1 | 1 | |
1 (0)| 00:00:01 | 0 |00:00:00.01 | 2 |
--------------------------------------------------------------------------------
----------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

1 - SEL$1 / T01@SEL$1
2 - SEL$1 / T01@SEL$1

Outline Data
-------------

/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('10.2.0.4')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
INDEX_RS_ASC(@"SEL$1" "T01"@"SEL$1" ("T01"."OBJECT_ID"))
END_OUTLINE_DATA
*/

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

2 - access("OBJECT_ID"=1)

Column Projection Information (identified by operation id):
-----------------------------------------------------------

1 - "T01"."OWNER"[VARCHAR2,30], "T01"."OBJECT_NAME"[VARCHAR2,128], "T01"."SUB
OBJECT_NAME"[VARCHAR2,30],
"OBJECT_ID"[NUMBER,22], "T01"."DATA_OBJECT_ID"[NUMBER,22], "T01"."OBJECT_
TYPE"[VARCHAR2,19], "T01"."CREATED"[DATE,7],
"T01"."LAST_DDL_TIME"[DATE,7], "T01"."TIMESTAMP"[VARCHAR2,19], "T01"."STA
TUS"[VARCHAR2,7], "T01"."TEMPORARY"[VARCHAR2,1],
"T01"."GENERATED"[VARCHAR2,1], "T01"."SECONDARY"[VARCHAR2,1]
2 - "T01".ROWID[ROWID,10], "OBJECT_ID"[NUMBER,22]

46 rows selected.

Iostats会显示sql语句中IO统计信息,要显示IO统计信息则需要设置statistics_level=all或者sql语句中增加gather_plan_statistics的hint,否则会出现上述的警告信息
Memstats会显示自动管理pga下消耗的内存资源
Allstats同时包含iostats和memstats信息
Last表示最后一次执行的统计信息,如果不加默认会显示所有执行次数的统计信息。

我们观察上面allstats last参数对应的执行计划,发觉执行计划中有一些改变:
Starts表示该执行步骤的循环次数(如果只看单次执行sql统计信息,这个次数一般都是1,但是对于nested loop,这个可能会变化)
E-Rows和E-Bytes分别表示执行cbo估算返回的rows和bytes
A-Rows和A-Bytes则分别表示实际执行sql语句时返回的rows和bytes
E-Time和A-Time则分别表示cbo估算执行该步骤执行计划消耗的时间和实际执行时消耗的时间
Buffer则表示该执行计划产生的逻辑读

可以对sql加上了hint gather_plan_statistics或者typical_statistics设置为all,结合dbms_xplan.display_cursor来抓取实际数据返回的行数和cbo估算返回的行数、观察哪一步执行计划最消耗时间等。

优化器统计信息不准造成cbo错误的估算了rows而选择了偏差的执行计划案例已经很多了,可以比较e_rows*start是否和a_rows有较大的偏差,buffer/a_rows读取每行平均消耗的逻辑读,对这些信息有一定了解后可以方便我们优化sql。

比如可以用hint gather_plan_statistics获得sql语句实际某个执行计划返回的cardinality后,直接加上hint cardinality来让cbo选择更合理的执行计划,不过由于业务数据一直在变化,这种加上cardinality hint的优化办法实用性并不高,更多是用于测试。

比如下列cardinality hint示例:
SQL> explain plan for select /*+gather_plan_statistics cardinality(t01 1)*/* fro
m t01 where object_id between 100 and 20000;

Explained.

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

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
----------------------------------------
Plan hash value: 3295674804

--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 93 | 158 (1)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| T01 | 1 | 93 | 158 (1)| 00:00:02 |
--------------------------------------------------------------------------

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

1 - filter("OBJECT_ID"<=20000 AND "OBJECT_ID">=100)

13 rows selected.

这里重点还是要对e_rows和a_rows来分析,看看何种原因造成优化器估算返回的rows和实际返回rows有较大的偏差。

再来看看dbms_xplan.display_sqlset函数:
Dbms_xplan.display_sqlset display the execution plan of a given statement stored in a SQL tuning set.
DBMS_XPLAN.DISPLAY_SQLSET(
sqlset_name IN VARCHAR2,
sql_id IN VARCHAR2,
plan_hash_value IN NUMBER := NULL,
format IN VARCHAR2 := 'TYPICAL',
sqlset_owner IN VARCHAR2 := NULL)
RETURN DBMS_XPLAN_TYPE_TABLE PIPELINED;

Dbms_xplan.display_sqlset函数用于显示存储在sql tuning中的执行计划

Sqlset_name和sql_id都没有缺省值
plan_hash_value默认为null,为显示其所有的执行计划
format跟上面的相同
sql_set_owner默认为当前用户下的sql tunning的执行计划

这里小鱼先花点时间补充下oracle 10g推出的sql tuning advisor(STA)
12.2 SQL Tuning Advisor
The Automatic SQL Tuning capabilities are exposed through a server utility called the SQL Tuning Advisor. The SQL Tuning Advisor takes one or more SQL statements as an input and invokes the Automatic Tuning Optimizer to perform SQL tuning on the statements. The output of the SQL Tuning Advisor is in the form of an advice or recommendations, along with a rationale for each recommendation and its expected benefit. The recommendation relates to collection of statistics on objects, creation of new indexes, restructuring of the SQL statement, or creation of SQL Profile. A user can choose to accept the recommendation to complete the tuning of the SQL statements.
Sql tuning advisor会根据sql语句来自动给出相应的优化建议,比如包括创建索引、统计信息,改写sql或者创建sql profile,用户可以接受这个建议来对sql语句进行优化。
Running SQL Tuning Advisor using DBMS_SQLTUNE package is a multi-step process:
1. Create a SQL Tuning Set (if tuning multiple SQL statements)
2. Create a SQL tuning task
3. Execute a SQL tuning task
4. Display the results of a SQL tuning task
5. Implement recommendations as appropriate

有一个生产环境的sql执行计划异常,造成了显著的cache buffer chains latch等待,我们拿到这个sql ID来用sql tuning advisor来进行优化:

DECLARE
my_task_name VARCHAR2 (100);
BEGIN
my_task_name :=
DBMS_SQLTUNE.create_tuning_task (sql_id => '2x138d7fx7sbv',
scope => 'COMPREHENSIVE',
time_limit => 60,
task_name => 'my_sql_tuning_task');
END;
/

execute dbms_sqltune.execute_tuning_task(task_name=>'my_sql_tuning_task')

select dbms_sqltune.report_tuning_task(task_name=>’my_sql_tuning_task’) from dual;

GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : my_sql_tuning_task
Tuning Task Owner : TEST
Workload Type : Single SQL Statement
Scope : COMPREHENSIVE
Time Limit(seconds): 60
Completion Status : INTERRUPTED
Started at : 05/22/2014 14:20:34
Completed at : 05/22/2014 14:21:38

-------------------------------------------------------------------------------
Error: ORA-13639: The current operation was interrupted because it timed out.
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
Schema Name: GH_CC
SQL ID : 2x138d7fx7sbv
SQL Text : select count(*) as listCount from
gh_cc.light_workflow_abstractticket tbl1 where
tbl1.sub_customer_no||tbl1.sub_service_name||tbl1.sub_address
in(select l.callnumber callnumber from (select
t.sub_customer_no||t.sub_service_name||t.sub_address
callnumber,count(t.sub_customer_no||t.sub_service_name||t.sub_add
ress) count1, 0 count2 from gh_cc.light_workflow_abstractticket
t where t.control_state
'2'and t.sub_service_name like '%报修%'
and t.sub_section_id = '19' and t.sub_service_id =
'szywsxshbxfgs' and t.create_time between '2014-05-01 14:04:07'
and '2014-05-22 00:00:00'group by
t.sub_customer_no||t.sub_service_name||t.sub_address) l group by
l.callnumber having sum(l.count1 + l.count2)>=2) and
tbl1.control_state
'2'and tbl1.sub_service_name like '%报修%'and
tbl1.sub_section_id = '19' and tbl1.sub_service_id =
'szywsxshbxfgs' and tbl1.create_time

推荐阅读
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了使用cacti监控mssql 2005运行资源情况的操作步骤,包括安装必要的工具和驱动,测试mssql的连接,配置监控脚本等。通过php连接mssql来获取SQL 2005性能计算器的值,实现对mssql的监控。详细的操作步骤和代码请参考附件。 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ... [详细]
  • 突破MIUI14限制,自定义胶囊图标、大图标样式,支持任意APP
    本文介绍了如何突破MIUI14的限制,实现自定义胶囊图标和大图标样式,并支持任意APP。需要一定的动手能力和主题设计师账号权限或者会主题pojie。详细步骤包括应用包名获取、素材制作和封包获取等。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
author-avatar
老鼠爱上毛ee
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有