In SQL quarry tuning one of the major goals is to eliminate FULL TABLE ACCESS. Using index we can achieve the goal. let see how it can be achieve
Suppose we have the following table
SQL> desc emp; Name Type ---------- ---------------------------- EMPNO NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2)Now enable the autotrace option to see sql quarry execution plan.SQL> set autotrace on;SQL>SQL> select * from emp;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- --------- ---------- ---------- ----------7369 SMITH CLERK 7902 17-DEC-80 800 207499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 307521 WARD SALESMAN 7698 22-FEB-81 1250 500 307566 JONES MANAGER 7839 02-APR-81 2975 207654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 307698 BLAKE MANAGER 7839 01-MAY-81 2850 307782 CLARK MANAGER 7839 09-JUN-81 2450 107788 SCOTT ANALYST 7566 19-APR-87 3000 207839 KING PRESIDENT 17-NOV-81 5000 107844 TURNER SALESMAN 7698 08-SEP-81 1500 0 307876 ADAMS CLERK 7788 23-MAY-87 1100 207900 JAMES CLERK 7698 03-DEC-81 950 307902 FORD ANALYST 7566 03-DEC-81 3000 207934 MILLER CLERK 7782 23-JAN-82 1300 1014 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 1218 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| EMP | 14 | 1218 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------
Update some rows for experimant purpose.SQL> update emp set sal=500 where sal<2000;8 row updated.SQL> commit;Commit complete.SQL> create unique index empno_emp on emp(empno);Index created.SQL> select empno from emp where empno>0; EMPNO---------- 7369 7499 7521 7566 7654 7698 7782 7788 7839 7844 7876 7900 7902 793414 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 182 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| EMP | 14 | 182 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------
The EMPNO_EMP index is not used because we access all 14 row.SQL> select empno from emp where empno<7700; EMPNO---------- 7369 7499 7521 7566 7654 76986 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 2992108249
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 78 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| EMPNO_EMP | 6 | 78 | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------
Here you can see the index is used because we access a portion of 14 rows.SQL> select empno from emp where sal=500; EMPNO---------- 7369 7499 7521 7654 7844 7876 7900 79348 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8 | 208 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| EMP | 8 | 208 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------
Again you can see the index is not used because indexed column empno in not prasent in the "WHERE" close.To ellimenate full table scane of previous sql quarry create an index on sal column which is in the "WHERE" close.SQL> create index sal_emp on emp(sal);Index created.SQL> select empno from emp where sal=500; EMPNO---------- 7369 7499 7521 7654 7844 7876 7900 79348 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 216044341
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8 | 208 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 8 | 208 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | SAL_EMP | 8 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
See ! we r abole to elliminate the full table scan..Learning: If you have an index and the indexed column is not present in "Where" close the index will not be used.Let go to our second experimant. for this drop the previously build indexsSQL> drop index empno_emp;Index dropped.SQL> drop index sal_emp;Index dropped.Create a composite indexSQL> create index EMPNO_SAL_EMP on emp(empno,sal);Index created.SQL> select empno from emp where empno<7900; EMPNO---------- 7369 7499 7521 7566 7654 7698 7782 7788 7839 7844 787611 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 615958546
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 143 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| EMPNO_SAL_EMP | 11 | 143 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------
SQL> select empno from emp where sal=500; EMPNO---------- 7369 7499 7521 7654 7844 7876 7900 79348 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 1761287244
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 8 | 208 | 1 (0)| 00:00:01 |
|* 1 | INDEX FULL SCAN | EMPNO_SAL_EMP | 8 | 208 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------
See EMPNO_SAL_EMP index experienced FULL SCAN because the quarry has sal (right part of index) in "WHERE" close.SQL> select ename,empno,deptno from emp where deptno=30 and sal=500;ENAME EMPNO DEPTNO---------- ---------- ----------ALLEN 7499 30WARD 7521 30MARTIN 7654 30TURNER 7844 30JAMES 7900 30Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 230 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| EMP | 5 | 230 | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------
Again an interesting thing .. now the table experienced FULL SCAN because select close has non indexed column and sal (right part of index) in "WHERE" close.SQL> select ename,deptno from emp where empno<7700;ENAME DEPTNO---------- ----------SMITH 20ALLEN 30WARD 30JONES 20MARTIN 30BLAKE 306 rows selected.Execution Plan
----------------------------------------------------------
Plan hash value: 1330938245
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 198 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMP | 6 | 198 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | EMPNO_SAL_EMP | 6 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
This time empno (left part of the index) prasent in the "WHERE"close. Learning : if you have composite index, make sure all/most of columns are present in "where" close in same order (suppose you have 3 column index and 2 &3 are in where close, the index is not used, you must have 1,2,3 or 1,2 or 1,3 colume in "WHERE" close)