[Chapter 5] Bulking Up with PL/SQL 8.1Chapter 5 5. Bulking Up with PL/SQL 8.1Contents:Context-Switching Problem ScenariosBulk DML with the FORALL StatementBulk Querying with the BULK COLLECT ClauseUsing Cursor AttributesAnalyzing the Impact of Bulk OperationsWe all know that PL/SQL is tightly integrated with the underlying SQL engine in the Oracle database. PL/SQL is the database programming language of choice for Oracle -- even if you now can at least theoretically use Java inside the database as well.But this tight integration does not necessarily mean that there isn't any overhead associated with running SQL from a PL/SQL program. When the PL/SQL runtime engine processes a block of code, it executes the procedural statements within its own engine, but it passes the SQL statements on to the SQL engine. The SQL layer executes the SQL statements and then returns information to the PL/SQL engine, if necessary.This transfer of control (shown in Figure 5.1) between the PL/SQL and SQL engines is called a context switch. Each time a switch occurs, there is additional overhead. There are a number of scenarios in which many switches occur and performance degrades. Oracle 8.1 now offers two enhancements to PL/SQL that allow you to bulk together multiple context switches into a single switch, thereby improving the performance of your applications.Figure 5.1: Context switching between PL/SQL and SQLThese new features are as follows:FORALLA variation on the FOR loop that bundles together multiple DML statements based on data in a collectionBULK COLLECTAn enhancement to implicit and explicit query cursor syntax that allows the transfer of multiple rows of data in a single round-trip between the PL/SQL and SQL enginesMake Collections a Part of Your PL/SQL DietWith each new release, PL/SQL gets more robust, faster, and easier to use. The "bulk bind" features discussed in this chapter, FORALL and BULK COLLECT, are clear reflections of this trend. As you will soon see, you won't be able to take advantage of FORALL and BULK COLLECT unless you work with collections (variable arrays, nested tables, or index-by tables). Sadly, many PL/SQL developers have not yet become conversant in these relatively new structures (variable arrays and nested tables are new with Oracle8; index-by tables were first available in PL/SQL 2.3 as "PL/SQL tables"). If you are one of those developers, perhaps these bulk bind capabilities will offer the required incentive for you to dig in to your books and knowledge bases.If you don't use collections and you don't use bulk bind operations, then the applications you write will run more slowly and be more complicated than you -- and your manager -- would like.5.1 Context-Switching Problem Scenarios Before we take a look at the details of FORALL and BULK COLLECT, let's examine the scenarios where excessive context switches are likely to cause problems. These are likely to happen when you are processing multiple rows of information stored (or to be deposited) in a collection (a VARRAY, nested table, index-by table, or host array).Suppose, for example, that I have filled two variable arrays with war criminals' ID numbers and the latest count of their victims. I then want to update the war criminals table with this information. Here's the solution I would have written prior to Oracle 8.1 (referencing a couple of already defined variable arrays):CREATE OR REPLACE PROCEDURE update_tragedies (
warcrim_ids IN name_varray,
num_victims IN number_varray
)
IS
BEGIN
FOR indx IN warcrim_ids.FIRST .. warcrim_ids.LAST
LOOP
UPDATE war_criminal
SET victim_count = num_victims (indx)
WHERE war_criminal_id = warcrim_ids (indx);
END LOOP;
END;If I needed to update 100 rows, then I would be performing 100 context switches, since each update is processed in a separate trip to the SQL engine. Figure 5.2 illustrates this excessive (but previously unavoidable) switching.Figure 5.2: Excessive context switching for multiple UPDATEsYou can also run into lots of switching when you fetch multiple rows of information from a cursor into a collection. Here is an example of the kind of code that cries out for the Oracle 8.1 bulk collection feature:DECLARE
CURSOR major_polluters IS
SELECT name, mileage
FROM cars_and_trucks
WHERE vehicle_type IN ('SUV', 'PICKUP');
names name_varray := name_varray();
mileages number_varray := number_varray();
BEGIN
FOR bad_car IN major_polluters
LOOP
names.EXTEND;
names (major_polluters%ROWCOUNT) := bad_car.name;
mileages.EXTEND;
mileages (major_polluters%ROWCOUNT) := bad_car.mileage;
END LOOP;
... now work with data in the arrays ...
END;If you find yourself writing code like either of the previous examples, you will be much better off switching to one of the bulk operations explored in the following sections. In particular, you should keep an eye out for these cues in your code: A recurring SQL statement inside a PL/SQL loop (it doesn't have to be a FOR loop, but that is the most likely candidate).Some parameter that can be made a bind variable. You need to be able to load those values into a collection to then have it processed by FORALL.4.7 NDS Utility Package5.2 Bulk DML with the FORALL Statement
Copyright (c) 2000 O'Reilly & Associates. All rights reserved.
Wyszukiwarka
Podobne podstrony:
ch05ch05ch05(ch05ch05ch05$ch05CH05ch05ch05ch05ch05ch05ch05!ch05ch05ch05więcej podobnych podstron