You are on page 1of 2

Consider an application that executes the following statements, which differ only

in literals:

SELECT SUM(salary) FROM hr.employees WHERE employee_id < 101;

SELECT SUM(salary) FROM hr.employees WHERE employee_id < 120;

SELECT SUM(salary) FROM hr.employees WHERE employee_id < 165;

The following query of V$SQLAREA shows that the three statements require three
different parent cursors. As shown by VERSION_COUNT, each parent cursor requires
its own child cursor.

COL SQL_TEXT FORMAT a30


SELECT SQL_TEXT, SQL_ID, VERSION_COUNT, HASH_VALUE
FROM V$SQLAREA
WHERE SQL_TEXT LIKE '%mployee%'
AND SQL_TEXT NOT LIKE '%SQL_TEXT%';

SQL_TEXT SQL_ID VERSION_COUNT HASH_VALUE


------------------------------ ------------- ------------- ----------
SELECT SUM(salary) FROM hr.emp b1tvfcc5qnczb 1 191509483
loyees WHERE employee_id < 165
SELECT SUM(salary) FROM hr.emp cn5250y0nqpym 1 2169198547
loyees WHERE employee_id < 101
SELECT SUM(salary) FROM hr.emp au8nag2vnfw67 1 3074912455
loyees WHERE employee_id < 120

Using bind varialbes :


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

VARIABLE emp_id NUMBER

EXEC :emp_id := 101;


SELECT SUM(salary) FROM hr.employees WHERE employee_id < :emp_id;

EXEC :emp_id := 120;


SELECT SUM(salary) FROM hr.employees WHERE employee_id < :emp_id;

EXEC :emp_id := 165;


SELECT SUM(salary) FROM hr.employees WHERE employee_id < :emp_id;

The following query of V$SQLAREA shows one unique SQL statement:

COL SQL_TEXT FORMAT a34


SELECT SQL_TEXT, SQL_ID, VERSION_COUNT, HASH_VALUE
FROM V$SQLAREA
WHERE SQL_TEXT LIKE '%mployee%'
AND SQL_TEXT NOT LIKE '%SQL_TEXT%';

SQL_TEXT SQL_ID VERSION_COUNT HASH_VALUE


---------------------------------- ------------- ------------- ----------
SELECT SUM(salary) FROM hr.employe 4318cbskba8yh 1 615850960
es WHERE employee_id < :emp_id

use bind variables instead of literals. You bind the same values (101, 120, and
165) to the bind variable :emp_id, and then display the execution plans for each:
VAR emp_id NUMBER

EXEC :emp_id := 101;


SELECT SUM(salary) FROM hr.employees WHERE employee_id < :emp_id;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
EXEC :emp_id := 120;
SELECT SUM(salary) FROM hr.employees WHERE employee_id < :emp_id;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
EXEC :emp_id := 165;
SELECT SUM(salary) FROM hr.employees WHERE employee_id < :emp_id;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR());
The DISPLAY_CURSOR output shows that the optimizer chose exactly the same plan for
all three statements:

SELECT SUM(salary) FROM hr.employees WHERE employee_id < :emp_id

Plan hash value: 2410354593

-----------------------------------------------------------------------------------
--
| Id | Operation | Name |Rows|Bytes|Cost (%CPU)|
Time|
-----------------------------------------------------------------------------------
--
| 0 | SELECT STATEMENT | | | |2 (100)|
|
| 1 | SORT AGGREGATE | |1|8 | |
|
| 2 | TABLE ACCESS BY INDEX ROWID BATCHED| EMPLOYEES |1|8 | 2 (0)| 00:00:01
|
|* 3 | INDEX RANGE SCAN | EMP_EMP_ID_PK |1| | 1 (0)| 00:00:01
|
-----------------------------------------------------------------------------------
--

Predicate Information (identified by operation id):


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

3 - access("EMPLOYEE_ID"<:EMP_ID)

You might also like