Oracle: Advanced PL/SQL: Performance
Module: Database-Specific Features
**1. Bulk Operations**: 10-100x faster than row-by-row. For 10,000 rows: FORALL = 0.3s, cursor = 30s.
**2. LIMIT Clause**: Use FETCH FIRST n ROWS ONLY with BULK COLLECT to avoid memory issues. Process 1000-10000 rows at a time.
**3. Dynamic SQL Overhead**: EXECUTE IMMEDIATE has parsing overhead. Use bind variables and cache execution plans when possible.
**4. Collection Memory**: Collections stored in PGA memory. Large collections (> 1M rows) can cause out of memory. Use pipelined functions for large result sets.
**5. Context Switches**: Each switch between PL/SQL and SQL takes 1-2ms. Bulk operations minimize switches (1 switch for 10,000 rows vs 10,000 switches).
**6. Pipelined Functions**: Stream results with constant memory. Regular functions materialize entire result set (memory proportional to result size).
Bulk operations 10-100x faster - FORALL processes 10,000 rows in 0.3s vs 30s row-by-row
Minimize context switches - each switch costs 1-2ms, bulk operations reduce from 10,000 to 1
Batch size matters - 1000-10000 rows optimal, too small (slow), too large (memory issues)
EXECUTE IMMEDIATE has parsing overhead - cache plans when possible, use bind variables
Pipelined functions stream results - constant memory vs regular functions (memory proportional to result size)
Collections stored in PGA - large collections (> 1M rows) can cause out of memory
PRAGMA AUTONOMOUS_TRANSACTION has overhead - use only when necessary (logging, auditing)
Not using bulk operations - row-by-row processing 10-100x slower
Loading entire dataset into memory - use batching with LIMIT clause
SQL injection in dynamic SQL - always use bind variables, never concatenate user input
Not validating dynamic identifiers - validate table/column names against whitelist
Ignoring %BULK_EXCEPTIONS - errors in FORALL can go unnoticed
Using cursors instead of bulk operations - cursors 10-100x slower
Not committing in batches - long transactions hold locks, cause blocking
Overusing PRAGMA AUTONOMOUS_TRANSACTION - creates overhead, use only for logging