If you can do this in pure SQL than in SQL, PL / SQL is not needed. With every SQL call in PL / SQL (or vice versa, but in this case less) there is overhead associated with each context switch between the two engines .. p>
Now, having said that, if you must do this in PL / SQL, then you can reduce the context switches by combining the entire collection into a DML statement in one operation.
Typically, cursor for loop uses an implicit bulk collect limit 100 , which is much better than an explicit cursor.
But, this is not just mass collection , we are dealing with operations that we will subsequently do in the array, which we added gradually. We could further improve performance using the FORALL statement and BULK COLLECT .
IMO, it is best to do this in pure SQL. If you really want to do this in PL / SQL, do it as I mentioned above.
I would go with the SQL approach, and since you have repeated the same subquery, I would use QUERY RESULT CACHE . Oracle 11g Introduces QUERY RESULT CACHE .
In your subquery:
SELECT /*+ RESULT_CACHE */ <column_list> .. <your subquery>...
For instance,
SQL> EXPLAIN PLAN FOR 2 SELECT 3 deptno, 4 AVG(sal) 5 FROM emp 6 GROUP BY deptno; Explained.
Look at the output of the plan tables:
SQL> SELECT * FROM TABLE(dbms_xplan.display); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------------- Plan hash value: 4067220884 -------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 3 | 21 | 3 (0)| 00:00:01 | | 1 | RESULT CACHE | b9aa181887ufz5341w1zqpf1d1 | | | | | | 2 | HASH GROUP BY | | 3 | 21 | 3 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL| EMP | 14 | 98 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------------------------------- PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------------- Result Cache Information (identified by operation id): ------------------------------------------------------ 1 - column-count=2; dependencies=(SCOTT.EMP); name="SELECT /*+ RESULT_CACHE */ deptno, AVG(sal) FROM emp GROUP BY deptno" 15 rows selected.