The following figure shows you the relationship between the PL/SQL engine and SQL Engine when excecuting an PL/SQL statement block: PL/SQL engine executes procedural statements but sends SQL statements to the SQL engine, which executes the SQL statements and, in some cases, returns data to the PL/SQL engine.
From the above figure, you should know that too many context switches between the PL/SQL and SQL engines will harm performance. That can happen when a loop executes a separate SQL statement for each element of a collection, specifying the collection element as a bind variable. For example, the following DELETE statement is sent to the SQL engine with each iteration of the FOR loop:
DECLARE
TYPE NumList IS VARRAY(20) OF NUMBER;
depts NumList := NumList(10, 30, 70); -- department numbers
BEGIN
...
FOR i IN depts.FIRST..depts.LAST LOOP
DELETE FROM emp WHERE deptno = depts(i);
END LOOP;
END;
In such cases, if the SQL statement affects four or more database rows, the use of bulk binds can improve performance considerably.
What Is Bulk Binds?
The assigning of values to PL/SQL variables in SQL statements is called binding. PL/SQL binding operations fall into three categories:
- in-bind: When a PL/SQL variable or host variable is stored in the database by an INSERT or UPDATE statement.
- out-bind: When a database value is assigned to a PL/SQL variable or a host variable by the RETURNING clause of an INSERT, UPDATE, or DELETE statement.
- define: When a database value is assigned to a PL/SQL variable or a host variable by a SELECT or FETCH statement.
A DML statement can transfer all the elements of a collection in a single operation, a process known as bulk binding. For example, if the collection has 20 elements, bulk binding lets you perform the equivalent of 20 SELECT, INSERT, UPDATE, or DELETE statements using a single operation. This technique improves performance by minimizing the number of context switches between the PL/SQL and SQL engines. With bulk binds, entire collections, not just individual elements, are passed back and forth.
- To do bulk binds with INSERT, UPDATE, and DELETE statements, you enclose the SQL statement within a PL/SQL FORALL statement.
- To do bulk binds with SELECT statements, you include the BULK COLLECT clause in the SELECT statement instead of using INTO.