一、如何查看SQL语句的执行计划  
     1、在SQL*PLUS环境中   
    执行SET AUTOTRACE ON 可以打开启动自动跟踪功能,如下(下面的红色字体是敲入的命令):     ChenZw>    set autotrace onChenZw>    select * from emp;
      EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO———- ———- ——— ———- ————– ———- ———- ———-      7369 SMITH      CLERK           7902 17-12月-80            800                    20      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30      7566 JONES      MANAGER         7839 02-4月 -81           2975                    20      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30      7782 CLARK      MANAGER         7839 09-6月 -81           2450                    10      7788 SCOTT      ANALYST         7566 19-4月 -87           3000                    20      7839 KING       PRESIDENT            17-11月-81           5000                    10      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30      7876 ADAMS      CLERK           7788 23-5月 -87           1100                    20      7900 JAMES      CLERK           7698 03-12月-81            950                    30      7902 FORD       ANALYST         7566 03-12月-81           3000                    20      7934 MILLER     CLERK           7782 23-1月 -82           1300                    10
 已选择14行。
 
 执行计划———————————————————-Plan hash value: 3956160932
 ————————————————————————–| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |————————————————————————–|   0 | SELECT STATEMENT  |      |    14 |   518 |     3   (0)| 00:00:01 ||   1 |  TABLE ACCESS FULL| EMP  |    14 |   518 |     3   (0)| 00:00:01 |————————————————————————–
 
 统计信息———————————————————-        476  recursive calls          0  db block gets         90  consistent gets          9  physical reads          0  redo size       1423  bytes sent via SQL*Net to client        416  bytes received via SQL*Net from client          2  SQL*Net roundtrips to/from client          7  sorts (memory)          0  sorts (disk)         14  rows processed          如同  ChenZw>    set linesize 200ChenZw>      
    2、在PL/SQL Developer软件中   
    在PL/SQL Developer窗口中,点击“文件”的“新建”菜单中选择“SQL窗口”,在里面输入自己要执行的SQL,例如上面的   SELECT * FROM EMP;   然后点击“F5”按钮,系统会自动弹出“解释计划窗口”,并且将该SQL的执行计划在“解释计划窗口”中显示出来   或者直接创建“解释计划窗口”也可以进入解释计划窗口。       现在回过头来看这个SQL语句,使用的是“  ChenZw>     select t.rowid,t.* from emp t;           
            ROWID              EMPNO ENAME  JOB       MGR HIREDATE    SAL  COMM DEPTNO           —————— —– —— ————- ————— —– ——           AAAQ+jAAEAAAAAeAAA  7369 SMITH  CLERK    7902 17-12月-80  800        20           AAAQ+jAAEAAAAAeAAB  7499 ALLEN  SALESMAN 7698 20-2月 -81 1600   300  30           AAAQ+jAAEAAAAAeAAC  7521 WARD   SALESMAN 7698 22-2月 -81 1250   500  30           AAAQ+jAAEAAAAAeAAD  7566 JONES  MANAGER  7839 02-4月 -81 2975        20           AAAQ+jAAEAAAAAeAAE  7654 MARTIN SALESMAN 7698 28-9月 -81 1250  1400  30           AAAQ+jAAEAAAAAeAAF  7698 BLAKE  MANAGER  7839 01-5月 -81 2850        30           AAAQ+jAAEAAAAAeAAG  7782 CLARK  MANAGER  7839 09-6月 -81 2450        10           AAAQ+jAAEAAAAAeAAH  7788 SCOTT  ANALYST  7566 19-4月 -87 3000        20           AAAQ+jAAEAAAAAeAAI  7839 KING   PRESIDENT     17-11月-81 5000        10           AAAQ+jAAEAAAAAeAAJ  7844 TURNER SALESMAN 7698 08-9月 -81 1500     0  30           AAAQ+jAAEAAAAAeAAK  7876 ADAMS  CLERK    7788 23-5月 -87 1100        20           AAAQ+jAAEAAAAAeAAL  7900 JAMES  CLERK    7698 03-12月-81  950        30           AAAQ+jAAEAAAAAeAAM  7902 FORD   ANALYST  7566 03-12月-81 3000        20           AAAQ+jAAEAAAAAeAAN  7934 MILLER CLERK    7782 23-1月 -82 1300        10    
        index unique  scan    索引唯一扫描,当可以优化器发现某个查询条件可以利用到主键、唯一键、具有外键约束的列,或者只是访问其中某行索引所在的数据的时候,优化器会选择这种扫描类型。
 第二种:   index range scan    索引范围扫描,当优化器发现在   index full scan    全索引扫描,如果要查询的数据可以全部从索引中获取,则使用全索引扫描。
 第四种:   index fast full scan    索引快速扫描,扫描索引中的全部的数据块,与全索引扫描的方式基本上类似。两者之间的明显的区别是,索引快速扫描对查询的数据不进行排序,数据返回的时候不是排序的。“在这种存取方法中,可以使用多块读功能,也可以使用并行读入,从而得到最大的吞吐量和缩短执行时间”。
 三、几种常见的索引类型的模拟      
    创建测试表以及测试数据的SQL:   
          USERID NUMBER(20),    NAME VARCHAR2(20),    DEPTNO NUMBER(20));–模拟数据BEGIN    FOR I IN 0..1000 LOOP        INSERT INTO TBL VALUES(        I,CONCAT(‘TBL’,I),MOD(I,2));    END LOOP;END;
 SELECT * FROM TBL;      
    1)  ChenZw>    select rowid,tbl.* from tbl where rownum<10;
 ROWID                  USERID NAME                     DEPTNO—————— ———- ——————– ———-AAAUhAAAEAAAAIcAAA        796 TBL796                        0AAAUhAAAEAAAAIcAAB        797 TBL797                        1AAAUhAAAEAAAAIcAAC        798 TBL798                        0AAAUhAAAEAAAAIcAAD        799 TBL799                        1AAAUhAAAEAAAAIcAAE        800 TBL800                        0AAAUhAAAEAAAAIcAAF        801 TBL801                        1AAAUhAAAEAAAAIcAAG        802 TBL802                        0AAAUhAAAEAAAAIcAAH        803 TBL803                        1AAAUhAAAEAAAAIcAAI        804 TBL804                        0      
    然后带着rowid去查询,看这个时候的执行计划:   ChenZw>   select * from tbl where rowid = ‘AAAUhAAAEAAAAIcAAA’;     执行计划———————————————————-Plan hash value: 2623095911
 ———————————————————————————–| Id  | Operation                  | Name | Rows  | Bytes | Cost (%CPU)| Time     |———————————————————————————–|   0 | SELECT STATEMENT           |      |     1 |    50 |     1   (0)| 00:00:01 ||   1 |  TABLE ACCESS BY USER ROWID| TBL  |     1 |    50 |     1   (0)| 00:00:01 |———————————————————————————–      上面的TABLE ACCESS BY USER ROWID是一种效率最高的获取数据的方法。   
    2)  index unique  scan   修改上面的表,增加一个主键,等于自动会增加一个唯一键约束:   ALTER TABLE TBL ADD CONSTRAINT TBLID PRIMARY KEY (USERID);   执行下面的SQL语句:   ChenZw>   select * from tbl where userid = 100;     执行计划———————————————————-Plan hash value: 1167568666
 ————————————————————————————-| Id  | Operation                   | Name  | Rows  | Bytes | Cost (%CPU)| Time     |————————————————————————————-|   0 | SELECT STATEMENT            |       |     1 |    38 |     2   (0)| 00:00:01 ||   1 |  TABLE ACCESS BY INDEX ROWID| TBL   |     1 |    38 |     2   (0)| 00:00:01 ||*  2 |   INDEX UNIQUE SCAN         | TBLID |     1 |       |     1   (0)| 00:00:01 |————————————————————————————-      
    从上面的执行计划可以看出,优化器首先是根据为刚才建立的索引TBLID来找到100的ROWID,然后根据ROWID去找到100所在的行数据。   
    2)  index full scan   为上面的表增加一个联合索引,在TBL.NAME和TBL.DEPTNO两个列上,SQL如下:   CREATE INDEX INDEX_TBL_NAME_DEPTNO ON TBL(NAME,DEPTNO);   
    3)  index range scan   执行下面的语句:     ChenZw>    select * from tbl where userid between 10 and 100;已选择91行。执行计划———————————————————-Plan hash value: 2314926374
 ————————————————
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!