Oracle里的执行计划

Posted 春困秋乏夏打盹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle里的执行计划相关的知识,希望对你有一定的参考价值。

1 执行计划的查看

 1 explan plan

 2 dbms_xplan包

 3 sqlplus中 set autot

 4 10046

 5 awr报告

 6一些现成的脚本

 7 10053

常见的就前4种

执行计划的补充信息

Note

-----

- dynamic sampling used for this statement

- cardinality feedback used for this statement

- sql profile sys_sqlprof_  used for this statement

1 explain plan

 Plsql developer中F5,Toad中ctrl+e,

create table testyhq (id1 number,name1 varchar2(20),date1 date default sysdate);
create table testyhq2 (id1 number,name1 varchar2(20),date1 date default sysdate);

insert  into testyhq  (id1,name1) values (1,\'yhq\');
insert  into testyhq2  (id1,name1) values (1,\'yhq\');

explain plan for
select * from testyhq t1
where  exists (select 1 from testyhq2 t2 where t1.id1=t2.id1);

select * from table(dbms_xplan.display);

 

 

2 dbms_xplan

select * from table(dbms_xplan.display)
select * from table(dbms_xplan.display_cursor(null,null,\'runstats_last\'));-all,advanced
select * from table(dbms_xplan.display_cursor(null,null,\'allstats last\'));
select * from table(dbms_xplan.display_cursor(\'dwcqthpyuzbgm\',null,\'typical -predicate -rows\'));

3 autot on

 set autot [off|on traceonly] [exp] [stat]

4 10046tkprof命令

 --详细见10046

2 如何得到真实的执行计划

  判断执行计划是否真实,要根据真正执行过

select count(*) from emp where ename=\'hongquan\';

select * from v$sqlarea where sql_text like\'select count(*) from emp%\'

--得到 sql_id

select * from table(dbms_xplan.display_cursor(\'dg5qqawqhkbay\',null,\'typical -predicate -rows\'));---advanced

-得到真实的执行计划

 

   - Warning: basic plan statistics not available. These are only collected when:

       * hint \'gather_plan_statistics\' is used for the statement or

       * parameter \'statistics_level\' is set to \'ALL\', at session or system level

 

SQL> conn scott
Enter password: 
Connected.
SQL> set linesize 1000
SQL> set pagesize 1000
SQL> SELECT ename,dname,loc                                         
  2    FROM   emp e, dept d                                           
  3    WHERE  e.deptno = d.deptno                                     
  4    AND    e.empno  = 7788;     
ENAME      DNAME          LOC
---------- -------------- -------------
SCOTT      RESEARCH       DALLAS
SQL> select * from table(dbms_xplan.display_cursor(null,null));

PLAN_TABLE_OUTPUT
SQL_ID  bbms3v8t5j4zr, child number 0
-------------------------------------
SELECT ename,dname,loc   FROM   emp e, dept d   WHERE  e.deptno = d.deptno
AND    e.empno  = 7788

Plan hash value: 2385808155
----------------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |       |       |     2 (100)|          |
|   1 |  NESTED LOOPS                |         |     1 |    33 |     2   (0)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| EMP     |     1 |    13 |     1   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN         | PK_EMP  |     1 |       |     0   (0)|          |
|   4 |   TABLE ACCESS BY INDEX ROWID| DEPT    |     4 |    80 |     1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN         | PK_DEPT |     1 |       |     0   (0)|          |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("E"."EMPNO"=7788)
   5 - access("E"."DEPTNO"="D"."DEPTNO")
24 rows selected.

SQL> select sql_id,address,plan_hash_value,hash_value,child_number from v$sql                                           
  2   where sql_text like \'%SELECT ename%\' and sql_text not like \'%from v$sql%\';   

SQL_ID        ADDRESS  PLAN_HASH_VALUE HASH_VALUE CHILD_NUMBER
------------- -------- --------------- ---------- ------------
d3kymurnb00vk 309E4398      2385808155 3903849330            0
bbms3v8t5j4zr 3094A978      2385808155  844665847            0

SQL> select * from table(dbms_xplan.display_cursor(\'bbms3v8t5j4zr\',null,\'typical -predicate -rows\'));

PLAN_TABLE_OUTPUT
SQL_ID  bbms3v8t5j4zr, child number 0
-------------------------------------
SELECT ename,dname,loc   FROM   emp e, dept d   WHERE  e.deptno =
d.deptno   AND    e.empno  = 7788
Plan hash value: 2385808155
--------------------------------------------------------------------------------
| Id  | Operation                    | Name    | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |         |       |     2 (100)|          |
|   1 |  NESTED LOOPS                |         |    33 |     2   (0)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| EMP     |    13 |     1   (0)| 00:00:01 |
|   3 |    INDEX UNIQUE SCAN         | PK_EMP  |       |     0   (0)|          |
|   4 |   TABLE ACCESS BY INDEX ROWID| DEPT    |    80 |     1   (0)| 00:00:01 |
|   5 |    INDEX UNIQUE SCAN         | PK_DEPT |       |     0   (0)|          |
--------------------------------------------------------------------------------
18 rows selected.

SQL> show parameter statistics_le
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
statistics_level                     string      TYPICAL
SQL> alter session set statistics_level=all;
Session altered.
SQL> select e.ename,e.sal,s.grade                                                                                        
  2   from emp e                                                                                                          
  3   join salgrade s                                                                                                     
  4   on e.sal between losal and hisal                                                                                    
  5   and e.deptno = 20; 
ENAME             SAL      GRADE
---------- ---------- ----------
SCOTT            3000          4
FORD             3000          4
JONES            2975          4
ADAMS            1100          1
SMITH             800          1

SQL> select * from table(dbms_xplan.display_cursor(null,null,\'iostats last -predicate -note\'));
PLAN_TABLE_OUTPUT
SQL_ID  d75njv99u8m2n, child number 0
-------------------------------------
select e.ename,e.sal,s.grade  from emp e  join salgrade s  on e.sal between losal and hisal
 and e.deptno = 20

Plan hash value: 4204027666
----------------------------------------------------------------------------------------------------
| Id  | Operation            | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
--------------------------------------------------------------------------------------------
|   1 |  MERGE JOIN          |          |      1 |      1 |      5 |00:00:00.04 |      14 |     11 |
|   2 |   SORT JOIN          |          |      1 |      5 |      5 |00:00:00.03 |       7 |      5 |
|   3 |    TABLE ACCESS FULL | EMP      |      1 |      5 |      5 |00:00:00.03 |       7 |      5 |
|   4 |   FILTER             |          |      5 |        |      5 |00:00:00.01 |       7 |      6 |
|   5 |    SORT JOIN         |          |      5 |      5 |     14 |00:00:00.01 |       7 |      6 |
|   6 |     TABLE ACCESS FULL| SALGRADE |      1 |      5 |      5 |00:00:00.01 |       7 |      6 |
----------------------------------------------------------------------------------------------------

18 rows selected.
SQL> alter session set statistics_level=typical;
Session altered.
SQL>  SELECT /*+ gather_plan_statistics */ ename,dname,loc                                                                
  2   FROM   emp e, dept d                                                                                                
  3    WHERE  e.deptno = d.deptno                                                                                          
  4    AND    d.deptno=20 ORDER BY 1,2,3; 
ENAME      DNAME          LOC
---------- -------------- -------------
ADAMS      RESEARCH       DALLAS
FORD       RESEARCH       DALLAS
JONES      RESEARCH       DALLAS
SCOTT      RESEARCH       DALLAS
SMITH      RESEARCH       DALLAS

SQL> select * from table(dbms_xplan.display_cursor(null,null,\'allstats -rows\'));  
PLAN_TABLE_OUTPUT
SQL_ID  cdazxuhca6j88, child number 0
-------------------------------------
 SELECT /*+ gather_plan_statistics */ ename,dname,loc  FROM   emp e, dept d   WHERE  e.deptno = d.deptno
AND    d.deptno=20 ORDER BY 1,2,3

Plan hash value: 3339094711
| Id  | Operation                     | Name    | Starts | A-Rows |   A-Time   | Buffers |  OMem |  1Mem |  O/1/M   |
---------------------------------------------------------------------------------------------------------------------
|   1 |  SORT ORDER BY                |         |      1 |      5 |00:00:00.01 |       9 |  2048 |  2048 |     1/0/0|
|   2 |   NESTED LOOPS                |         |      1 |      5 |00:00:00.01 |       9 |       |       |          |
|   3 |    TABLE ACCESS BY INDEX ROWID| DEPT    |      1 |      1 |00:00:00.01 |       2 |       |       |          |
|*  4 |     INDEX UNIQUE SCAN         | PK_DEPT |      1 |      1 |00:00:00.01 |       1 |       |       |          |
|*  5 |    TABLE ACCESS FULL          | EMP     |      1 |      5 |00:00:00.01 |       7 |       |       |          |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("D"."DEPTNO"=20)
   5 - filter("E"."DEPTNO"=20)

23 rows selected.
SQL>

3 查看执行计划的执行顺序

  同级,最上,最右,

---- ----安装一个xplan

select * from table(xplan.display_cursor(null,null,\'runstats_last\'));

 

4 oracle里常见的执行计划

1 与表访问相关

 TABLE ACCESS FULL

 TABLE ACCESS BY USER ROWID

 TABLE ACCESS BY INDEX ROWID

2与b tree index 相关

 INDEX UNIQURE INDEX SCAN

 INDEX RANGE SCAN

 INDEX FULL SCAN

 INDEX FAST FULL SCAN

 INDEX SKIP SCAN

3与表连接相关

 SORT JOIN ,MERGE JOIN

 NESTED LOOPS,

HASH JOIN,

NESTED LOOPS ANTI,SEMI,MERGE JOIN

Anti:not in,not exists

Semi:in,exists----半连接会对连接结果进行必要的去重

--分区

--http://www.dbaxiaoyu.com/archives/1780

位图索引相关的执行计划

位图索引主要用于数据仓库或者dss系统,位图索引实现了快捷的按位运算

位图索引没有行锁的概念,要锁就锁索引行的整个位图段,多个数据行可能对应于同一个索引行的位图段

位图索引:如果索引行的distinct值比较少,那么与b树索引比较,会占用较少的存储空间,能够快速处理and,or的条件的sql

位图索引,会存储为null值的列(及时是单键值)

5 其他典型的执行计划

 1 and-equal(index merge)

 Where出了多个不同单列的等值条件,并且多列上有单键的index,则会根据相应的单个index去扫描这些index

SQL> set linesize 800
SQL> set pagesize 1000
SQL> set autot trace
SQL>  create index idx_empno on emp_t(empno);
Index created.
SQL>  create index idx_mgr on emp_t(mgr);
Index created.
SQL>  select /*+ and_equal( emp_t idx_empno idx_mgr)*/ empno,job,ename,mgr from emp_t where empno=7566 and mgr=7839;
Execution Plan
----------------------------------------------------------
Plan hash value: 3378047620
-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     1 |    22 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| EMP_T     |     1 |    22 |     2   (0)| 00:00:01 |
|   2 |   AND-EQUAL                 |           |       |       |            |          |
|*  3 |    INDEX RANGE SCAN         | IDX_EMPNO |     1 |       |     1   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN         | IDX_MGR   |     2 |       |     1   (0)| 00:00:Oracle执行计划里的 access和filter有什么区别

Oracle删除一条SQL在Shared Pool里缓存的执行计划的三种方法

Oracle看懂执行计划系列之稳定执行计划

Oracle_sql优化基础——优化器总结

Oracle里收集与查看统计信息的方法

plsql F5执行计划怎么看