Oracle 11g PL/SQL notes

9,543 views

Published on

Oracle 11g New features for Developers

Published in: Technology
0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
9,543
On SlideShare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
618
Comments
0
Likes
10
Embeds 0
No embeds

No notes for slide

Oracle 11g PL/SQL notes

  1. 1. AgendaOracle PL/SQL usage and 11g new features for Developers for DBAs • Row by row processing • Nested row by row processing • Lookup queries • Result Cache for lookup queries • Excessive access to DUAL • Populating Master-Detail Rows • Unnecessary Function Execution • Excessive Parsing • Excessive Commits • SIMPLE_INTEGER Datatype • Continue Statement • Sequences in PL/SQL expressions • Dynamic SQL Enhancements • Native Compilation • Automatic Subprogram Inlining • READ ONLY Tables • INVISIBLE indexes • SQL_monitoring • History Tables & Enterprise Manager • References Y. Anıl Akduygu October - 2012
  2. 2. Row-by-Row ProcessingDO NOT USE USEDECLARE --CURSOR c1 IS -- Insert in to target tableSELECT prod_id, cust_id, time_id, amount_sold --FROM salesWHERE amount_sold > 100;c1_rec c1%rowtype; INSERT INTO top_sales_customers (prod_id,l_cust_first_name customers.cust_first_name%TYPE; cust_id,l_cust_lasT_name customers.cust_last_name%TYPE;BEGIN time_id,FOR c1_rec IN c1 cust_first_name,LOOP cust_last_name,-- Query customer details amount_sold)SELECT cust_first_name, cust_last_name SELECT s.prod_id,INTO l_cust_first_name, l_cust_last_name s.cust_id,FROM customers s.time_id,WHERE cust_id=c1_rec.cust_id; c.cust_first_name,-- c.cust_last_name,-- Insert in to target table s.amount_sold-- FROM sales s, customers cINSERT INTO top_sales_customers (prod_id, cust_id, time_id, cust_first_name, cust_last_name,amount_sold WHERE s.cust_id = c.cust_id AND s.amount_sold > 100;)VALUES(c1_rec.prod_id,c1_rec.cust_id,c1_rec.time_id,l_cust_first_name,l_cust_last_name,c1_rec.amount_sold);END LOOP;COMMIT;END;SQL statements are called from PL/SQLin a loop, so the execution will switch back and forth between the PL/SQL engine and the SQL engine.This switch between two environments is known as a context switch. Context switches increase elapsed time of your programs
  3. 3. Nested Row-by-Row ProcessingDO NOT USE USEDECLARE MERGE INTO fact1 USINGCURSOR c1 AS (SELECT DISTINCT c3.n1,c3.n2 SELECT n1 FROM t1; FROM t1, t2, t3CURSOR c2 (p_n1) AS WHERE t1.n1 = t2.n1 SELECT n1, n2 FROM t2 WHERE n1=p_n1; AND t2.n1 = t3.n1CURSOR c3 (p_n1, p_n2) AS AND t2.n2 = t3.n2) t SELECT text FROM t3 WHERE n1=p_n1 AND n2=p_n2; ON (fact1.n1=t.n1 AND fact1.n2=t.n2)BEGIN WHEN matched THENFOR c1_rec IN c1 UPDATE SET .. WHEN NOT matched THENLOOP INSERT .. ; FOR c2_rec IN c2 (c1_rec.n1) COMMIT; LOOP ; FOR c3_rec IN c3(c2_rec.n1, c2_rec.n2) LOOP-- execute some sql here; UPDATE … SET ..where n1=c3_rec.n1 AND n2=c3_rec.n2; EXCEPTION WHEN no_data_found THEN INSERT into… END; END LOOP; END LOOP; END LOOP;COMMIT;END;/Do not write code with deeply nested cursors in PL/SQL language. Review it to see if you can write such code in SQL instead.
  4. 4. Lookup QueriesDO NOT USE USE DECLAREDECLARE CURSOR c1 CURSOR c1 IS IS SELECT prod_id,cust_id,time_id, SELECT prod_id, amount_sold cust_id, FROM sales time_id, WHERE amount_sold > 100; amount_sold FROM sales l_country_names country_names_type; WHERE amount_sold > 100; l_Country_id countries.country_id%TYPE; l_country_name countries.country_name%TYPE; l_cust_first_name customers.cust_first_name%TYPE; l_cust_first_name customers.cust_first_name%TYPE; l_cust_last_name customers.cust_last_name%TYPE; l_cust_lasT_name customers.cust_last_name%TYPE; l_Country_id countries.country_id%TYPE; l_country_name countries.country_name%TYPE; TYPE country_names_typeBEGIN IS FOR c1_rec IN c1 TABLE OF VARCHAR2 (40) LOOP INDEX BY PLS_INTEGER; -- Query customer details SELECT cust_first_name, cust_last_name, country_id l_country_names country_names_type; INTO l_cust_first_name, l_cust_last_name, l_country_id BEGIN FROM customers FOR c1_rec IN c1 WHERE cust_id = c1_rec.cust_id; LOOP -- Query customer details -- Query to get country_name SELECT cust_first_name, cust_last_name, country_id SELECT country_name INTO l_cust_first_name, l_cust_last_name, l_country_id INTO l_country_name FROM customers FROM countries WHERE cust_id = c1_rec.cust_id; WHERE country_id = l_country_id; -- Check array first before executing a SQL statement -- IF (l_country_names.EXISTS (l_country_id)) -- Insert in to target table THEN -- l_country_name := l_country_names (l_country_id); INSERT INTO top_sales_customers (prod_id, ELSE cust_id, SELECT country_name time_id, INTO l_country_name cust_first_name, FROM countries cust_last_name, WHERE country_id = l_country_id; amount_sold, -- Store in the array for further reuse country_name) l_country_names (l_country_id) := l_country_name; VALUES (c1_rec.prod_id, END IF; c1_rec.cust_id, -- Insert in to target table c1_rec.time_id, INSERT INTO top_sales_customers l_cust_first_name, (prod_id,cust_id,time_id,cust_first_name, l_cust_last_name, cust_last_name,amount_sold,country_name) c1_rec.amount_sold, VALUES l_country_name); (c1_rec.prod_id,c1_rec.cust_id,c1_rec.time_id,l_cust_first_name, END LOOP; l_cust_last_name,c1_rec.amount_sold,l_country_name); END LOOP; COMMIT;END; COMMIT;• / END; / You can define an associative array to cache the results of the lookup query and reuse the array in later executions, thus effectively reducing the executions of the lookup query.
  5. 5. Result Cache for Lookup QueriesDO NOT USE USE DECLAREDECLARE CURSOR c1 CURSOR c1 IS IS SELECT prod_id, SELECT prod_id, cust_id, cust_id, time_id, time_id, amount_sold amount_sold FROM sales FROM sales WHERE amount_sold > 100; WHERE amount_sold > 100; l_cust_first_name customers.cust_first_name%TYPE; l_cust_first_name customers.cust_first_name%TYPE; l_cust_last_name customers.cust_last_name%TYPE; l_cust_last_name customers.cust_last_name%TYPE; l_Country_id countries.country_id%TYPE; l_Country_id countries.country_id%TYPE; l_country_name countries.country_name%TYPE; l_country_name countries.country_name%TYPE; BEGINBEGIN FOR c1_rec IN c1 FOR c1_rec IN c1 LOOP LOOP -- Query customer details -- Query customer details SELECT cust_first_name, cust_last_name, country_id SELECT cust_first_name, cust_last_name, country_id INTO l_cust_first_name, l_cust_last_name, l_country_id INTO l_cust_first_name, l_cust_last_name, l_country_id FROM customers FROM customers WHERE cust_id = c1_rec.cust_id; WHERE cust_id = c1_rec.cust_id; -- Query to get country_name -- Query to get country_name SELECT country_name SELECT /*+ RESULT_CACHE */ country_name INTO l_country_name INTO l_country_name FROM countries FROM countries WHERE country_id = l_country_id; WHERE country_id = l_country_id; -- -- -- Insert in to target table -- Insert in to target table -- -- INSERT INTO top_sales_customers (prod_id, INSERT INTO top_sales_customers (prod_id, cust_id, cust_id, time_id, time_id, cust_first_name, cust_first_name, cust_last_name, cust_last_name, amount_sold, amount_sold, country_name) country_name) VALUES (c1_rec.prod_id, VALUES (c1_rec.prod_id, c1_rec.cust_id, c1_rec.cust_id, c1_rec.time_id, c1_rec.time_id, l_cust_first_name, l_cust_first_name, l_cust_last_name, l_cust_last_name, c1_rec.amount_sold, c1_rec.amount_sold, l_country_name); l_country_name); END LOOP; END LOOP; COMMIT; COMMIT; END;END; // The result cache is new to Oracle 11g and provides enhanced query performance for SQL and PL/SQL applications by caching the results of SQL queries into memory . A result cache shareable and is stored in SGA memory.
  6. 6. Excessive Access to DUALDO NOT USE USEDECLARE DECLARE l_epoch INTEGER; l_epoch INTEGER;BEGIN BEGIN SELECT ( (SYSDATE l_epoch := - TO_DATE (01-JAN-1970 00:00:00, DD-MON-YYYY HH24:MI:SS)) (SYSDATE - TO_DATE (01-JAN-1970 00:00:00, DD-MON-YYYY HH24:MI:SS)) * 24 * 24 * 60 * 60 * 60) * 60; INTO l_epoch FROM DUAL; DBMS_OUTPUT.put_line (l_epoch); END; DBMS_OUTPUT.put_line (l_epoch); /END;/You should avoid overusing DUAL table access. Accessing DUAL from PL/SQL causes context switching, which hurts performance.
  7. 7. Excessive Access to DUALDO NOT USE USEDECLARE l_cust_id NUMBER; INSERT INTO customers_histBEGIN SELECT cust_hist_id_seq.NEXTVAL, cust_first_name, cust_last_name FOR c1 IN (SELECT cust_first_name, cust_last_name FROM customers FROM customers WHERE cust_marital_status != married; WHERE cust_marital_status != married) LOOP SELECT cust_hist_id_seq.NEXTVAL INTO l_cust_id FROM DUAL; INSERT INTO customers_hist (cust_hist_id, first_name, last_name) VALUES (l_cust_id, c1.cust_first_name, c1.cust_last_name); END LOOP;END;/You should avoid overusing DUAL table access. Accessing DUAL from PL/SQL causes context switching, which hurts performance.
  8. 8. Populating Master-Detail RowsDO NOT USE USEDECLARE l_cust_id NUMBER; INSERT INTO customers (cust_id, ...)BEGIN VALUES (cust_id_seq.nextval,...) FOR c1 IN (SELECT cust_first_name, cust_last_name RETURNING cust_id into l_cust_id; FROM customers WHERE cust_marital_status != married) INSERT INTO customer_transactions (cust_id, ...) LOOP VALUES (l_cust_id,...) SELECT cust_hist_id_seq.NEXTVAL INTO l_cust_id FROM DUAL; ... INSERT INTO customers_hist (cust_hist_id, first_name, last_name) VALUES (l_cust_id, c1.cust_first_name, c1.cust_last_name); END LOOP;END;/You can retrieve the key value from a newly-inserted master row by using the DML RETURNING clause. Then you can use that key value while inserting into the detail table.
  9. 9. Unnecessary Function ExecutionDO NOT USE USECREATE TABLE log_table (message_seq NUMBER, MESSAGE VARCHAR2 (512)); DECLARECREATE SEQUENCE message_id_seq; l_debug BOOLEAN := FALSE; r1 INTEGER;DECLARE l_debug BOOLEAN := FALSE; FUNCTION log_entry (v_message IN VARCHAR2, v_debug IN BOOLEAN) r1 INTEGER; RETURN NUMBER IS FUNCTION log_entry (v_message IN VARCHAR2, v_debug IN BOOLEAN) BEGIN RETURN NUMBER IF (v_debug) IS THEN BEGIN INSERT INTO log_table (message_seq, MESSAGE) IF (v_debug) VALUES (message_id_seq.NEXTVAL, v_message); THEN END IF; INSERT INTO log_table (message_seq, MESSAGE) VALUES (message_id_seq.NEXTVAL, v_message); RETURN 0; END IF; END; BEGIN RETURN 0; FOR c1 IN (SELECT s.prod_id, END; s.cust_id,BEGIN s.time_id, FOR c1 IN (SELECT s.prod_id, c.cust_first_name, s.cust_id, c.cust_last_name, s.time_id, s.amount_sold c.cust_first_name, FROM sales s, customers c c.cust_last_name, WHERE s.cust_id = c.cust_id AND s.amount_sold > 100) s.amount_sold LOOP FROM sales s, customers c $IF $$debug_on WHERE s.cust_id = c.cust_id AND s.amount_sold > 100) $THEN LOOP IF c1.cust_first_name IS NOT NULL IF c1.cust_first_name IS NOT NULL THEN THEN r1 := log_entry (first_name is not null , l_debug); r1 := log_entry (first_name is not null , l_debug); END IF; END IF; IF c1.cust_last_name IS NOT NULL IF c1.cust_last_name IS NOT NULL THEN THEN r1 := log_entry (Last_name is not null , l_debug); r1 := log_entry (Last_name is not null , l_debug); END IF; END IF; $END END LOOP; NULL;END; END LOOP;/ END; / Executing a function call usually means that a different part of the instruction set must be loaded into the CPU. By avoiding unnecessary function execution, you avoid unneeded flushing and refilling of the instruction pipeline, thus minimizing demands upon your CPU.
  10. 10. Unnecessary Function ExecutionDO NOT USE USECREATE OR REPLACE FUNCTION calculate_epoch (d IN DATE) CREATE INDEX compute_epoch_fbi ON sales RETURN NUMBER (calculate_epoch(time_id)) DETERMINISTIC PARALLEL (DEGREE 4);IS l_epoch NUMBER; SELECTBEGIN MAX (calculate_epoch (s.time_id)) epoch l_epoch := FROM sales s (d - TO_DATE (01-JAN-1970 00:00:00, DD-MON-YYYY HH24:MI:SS)) WHERE s.amount_sold > 100 * 24 AND calculate_epoch (s.time_id) BETWEEN 1000000000 AND 1100000000; * 60 * 60; RETURN l_epoch;END calculate_epoch;/SELECT MAX (calculate_epoch (s.time_id)) epoch FROM sales sWHERE s.amount_sold > 100 AND calculate_epoch (s.time_id) BETWEEN 1000000000 AND 1100000000;Executing a function call usually means that a different part of the instruction set must be loaded into the CPU. By avoiding unnecessary functionexecution, you avoid unneeded flushing and refilling of the instruction pipeline, thus minimizing demands upon your CPU.
  11. 11. Unnecessary Function ExecutionDO NOT USE USECREATE OR REPLACE FUNCTION calculate_epoch (d IN DATE) • CREATE OR REPLACE FUNCTION calculate_epoch (d IN date) RETURN NUMBER • RETURN NUMBER DETERMINISTIC RESULT_CACHE IS DETERMINISTIC • l_epoch number;IS • BEGIN l_epoch NUMBER; • l_epoch := (d - TO_DATE(01-JAN-1970 00:00:00, DD-MON-YYYY HH24:MI:SS))BEGIN • * 24 *60 *60 ; l_epoch := • RETURN l_epoch; (d - TO_DATE (01-JAN-1970 00:00:00, DD-MON-YYYY HH24:MI:SS)) • END calculate_epoch; * 24 • / * 60 * 60; • SELECT RETURN l_epoch; • MAX (calculate_epoch (s.time_id)) epochEND calculate_epoch; • FROM sales s/ • WHERE s.amount_sold > 100 • AND calculate_epoch (s.time_id) BETWEEN 1000000000 AND 1100000000;SELECT MAX (calculate_epoch (s.time_id)) epoch FROM sales sWHERE s.amount_sold > 100 AND calculate_epoch (s.time_id) BETWEEN 1000000000 AND 1100000000;The result cache is new to Oracle 11g and provides enhanced query performance for SQL and PL/SQL applications by caching the results of SQL queriesinto memory . A result cache shareable and is stored in SGA memory
  12. 12. Database Link CallsDO NOT USE USEDECLAREV_customer_name VARCHAR2(32); CREATE MATERIALIZED VIEW customers_snapshotBEGIN ...... ASFOR c1 IN (SELECT …) SELECT customer_name .. FROM customers@remotedb;LOOP... SELECT customer_name DECLARE INTO v_customer_name V_customer_name VARCHAR2(32); FROM customers@remotedb BEGIN WHERE account_id = c1.account_id; ...... FOR c1 IN (SELECT …)END LOOP/ ... SELECT customer_name INTO v_customer_name FROM customers_snapshot WHERE account_id = c1.account_id; ... END /Excessive database link-based calls can affect application performance. Accessing a remote table or modifying a remote table over a database link within aloop is not a scalable approach. For each access to a remote table, several SQL*Net packets are exchanged between the databases involved in thedatabase link.
  13. 13. Excessive ParsingDO NOT USE USEDECLARE DECLARE... ...BEGIN BEGINFOR c1_rec IN c1 FOR c1_rec IN c1LOOP LOOP-- Query customer details -- Query customer detailsEXECUTE IMMEDIATESELECT cust_first_name, cust_last_name, country_idFROM customers SELECT cust_first_name, cust_last_name, country_id intoWHERE cust_id= || c1_rec.cust_id INTO l_cust_first_name, l_cust_first_name, l_cust_last_name, l_cust_last_name, l_country_id; l_country_id... WHERE cust_id=c1_rec.cust_id;END LOOP;COMMIT; ...END; END LOOP;/ COMMIT; END; /Do not use literals , Use Bind variables in SQL statements. Using literals causes excessive hard parsing stresses the library cache, thereby reducing theapplication’s scalability and concurrency.
  14. 14. Excessive CommitsDO NOT USE USE DECLAREDECLARE commit_number pls_integer;BEGIN BEGINFOR c1_rec IN c1 commit_number := 0;LOOP FOR c1_rec IN c1 LOOP-- Query customer details -- Query customer detailsSELECT cust_first_name, cust_last_name, country_id into SELECT cust_first_name, cust_last_name, country_id into l_cust_first_name, l_cust_first_name, l_cust_last_name, l_cust_last_name, l_country_id l_country_id WHERE cust_id=c1_rec.cust_id; WHERE cust_id=c1_rec.cust_id; INSERT ... INSERT ... UPDATE ... UPDATE ... if commit_number > 10000 Commit; ThenEND LOOP; commit; commit_number := 0; end if;END;/ commit_number := commit_number + 1; END LOOP; Commit; END; /Frequent commits generate more redo, require Log Writer to flush the contents of log buffer to log file frequently, can lead to data integrity issues, andconsume more resources.
  15. 15. Type Usage in Spec DefinetionsDO NOT USE USECREATE OR REPLACE PACKAGE check_bilgi CREATE OR REPLACE PACKAGE check_bilgiIS IS... ...FUNCTION checkirtibatbilgi ( FUNCTION checkirtibatbilgi ( pcif IN t_mus_irtibat.client_no%TYPE, pcif IN NUMBER, pirtbilgi IN t_mus_irtibat.irtbilgi%TYPE, pirtbilgi IN VARCHAR2, pbilgitip IN t_mus_irtibat.bilgitip%TYPE, pbilgitip IN VARCHAR2, pserino IN t_mus_irtibat.musserino%TYPE DEFAULT NULL pserino IN NUMBER DEFAULT NULL ) ) RETURN BOOLEAN; RETURN BOOLEAN;.... ....END; END;/ / If you are using packages in distributed environment ; do not use Type in Packege Spec definition. By this way, you can reduce database dependencies .
  16. 16. PL/SQL New Features SIMPLE_INTEGER DatatypeThe SIMPLE_INTEGER datatype is a subtype of the PLS_INTEGER datatype and can dramatical increase the speed of integer arithmeticCREATE OR REPLACE PROCEDURE simple_integer_test_proc AS l_start NUMBER; l_loops NUMBER := 10000000; l_pls_integer PLS_INTEGER := 0; l_pls_integer_incr PLS_INTEGER := 1; l_simple_integer SIMPLE_INTEGER := 0; l_simple_integer_incr SIMPLE_INTEGER := 1;BEGIN l_start := DBMS_UTILITY.get_time; FOR i IN 1 .. l_loops LOOP l_pls_integer := l_pls_integer + l_pls_integer_incr; END LOOP; DBMS_OUTPUT.put_line(PLS_INTEGER: || (DBMS_UTILITY.get_time - l_start) || hsecs); l_start := DBMS_UTILITY.get_time; FOR i IN 1 .. l_loops LOOP l_simple_integer := l_simple_integer + l_simple_integer_incr; END LOOP; DBMS_OUTPUT.put_line(SIMPLE_INTEGER: || (DBMS_UTILITY.get_time - l_start) || hsecs);END simple_integer_test_proc;/
  17. 17. PL/SQL New Features Continue StatementThe CONTINUE statement jumps out of the current loop interation and starts the next one. It can be used on its own, or as part of CONTINUE WHEN statementDECLARE l_number NUMBER := 0;BEGIN FOR i IN 1 .. 100 LOOP CONTINUE WHEN MOD(i,2) = 0; -- Do something here! l_number := l_number + 1; END LOOP; DBMS_OUTPUT.put_line(CONTINUE WHEN : || l_number); l_number := 0; FOR i IN 1 .. 100 LOOP IF MOD(i,2) = 0 THEN CONTINUE; END IF; -- Do something here! l_number := l_number + 1; END LOOP; DBMS_OUTPUT.put_line(IF .. CONTINUE: || l_number);END;/
  18. 18. PL/SQL New Features Sequences in PL/SQL expressionsThe NEXTVAL and CURRVAL sequence pseudocolumns can now be accessed in PL/SQL expressions as well as queries.CREATE SEQUENCE test1_seq START WITH 1000000;DECLARE l_start NUMBER; l_loops NUMBER := 100000; l_value NUMBER;BEGINFOR i IN 1 .. l_loops LOOP l_value := test1_seq.NEXTVAL;END LOOP; FOR i IN 1 .. l_loops LOOP SELECT test1_seq.NEXTVAL INTO l_value FROM dual; END LOOP; FOR i IN 1 .. l_loops LOOP l_value := test1_seq.NEXTVAL; END LOOP; FOR i IN 1 .. l_loops LOOP SELECT test1_seq.CURRVAL INTO l_value FROM dual; END LOOP; l_start := DBMS_UTILITY.get_time; FOR i IN 1 .. l_loops LOOP l_value := test1_seq.CURRVAL; END LOOP;END;
  19. 19. PL/SQL New Features Dynamic SQL Enhancements Native dynamic SQL and the DBMS_SQL package now support dynamic SQL statements larger than 32 KB. The EXECUTE IMMEDIATE statement, OPEN-FOR statement and DBMS_SQL.PARSE procedure all accept SQL statements in the form of CLOBs. The DBMS_SQL.TO_REFCURSOR function converts a DBMS_SQL cursor ID into a REF CURSOR.DECLARE l_ref_cursor SYS_REFCURSOR; l_cursor NUMBER; l_count NUMBER := 0;BEGIN OPEN l_ref_cursor FOR SELECT * FROM emp; l_cursor := DBMS_SQL.to_cursor_number(l_ref_cursor); WHILE DBMS_SQL.fetch_rows(l_cursor) > 0 LOOP l_count := l_count + 1; END LOOP; DBMS_OUTPUT.put_line(Employee Count: || l_count); DBMS_SQL.close_cursor(l_cursor);END;/
  20. 20. PL/SQL New Features Automatic Subprogram InliningAutomatic subprogram inlining replace the subprogram calls with a copy of the code in the subprogram at compile time.Reduce the overheads associated with calling subprogramsALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=2;DECLARE l_loops NUMBER := 10000000; l_start NUMBER; l_return NUMBER; FUNCTION add_numbers (p_1 IN NUMBER, p_2 IN NUMBER) RETURN NUMBER AS BEGIN RETURN p_1 + p_2; END add_numbers;BEGIN FOR i IN 1 .. l_loops LOOP PRAGMA INLINE (add_numbers, YES); l_return := add_numbers(1, i); END LOOP;END;/
  21. 21. PL/SQL New Features Native CompilationIn Oracle 11g, PL/SQL native compilation requires no C compiler, no DBA intervention and is fully supported in a RAC environment.By setting the PLSQL_CODE_TYPE to a value of NATIVE, rather than the default value of INTERPRETED, code is compiled directly to machine codeand stored in the SYSTEM tablespace.When the code is called, it is loaded into shared memory, making it accessible for all sessions in that instance. The %_PLSQL_OBJECT_SETTINGSviews include the current PLSQL_CODE_TYPE setting for each PL/SQL object.Determining Whether to Use PL/SQL Native Compilation ( from Oracle® Database PL/SQL Language Reference)While you are debugging program units and recompiling them frequently, interpreted mode has these advantages:• You can use PL/SQL debugging tools on program units compiled for interpreted mode (but not for those compiled for native mode).• Compiling for interpreted mode is faster than compiling for native mode.After the debugging phase of development, in determining whether to compile a PL/SQL unit for native mode, consider:• PL/SQL native compilation provides the greatest performance gains for computation-intensive procedural operations. Examples are data warehouse applications and applications with extensive server-side transformations of data for display.• PL/SQL native compilation provides the least performance gains for PL/SQL subprograms that spend most of their time running SQL.• When many program units (typically over 15,000) are compiled for native execution, and are simultaneously active, the large amount of shared memory required might affect system performance.
  22. 22. New Featues for Developers & DBAs READ ONLY Tables• In previous Oracle releases, tables could be made to appear read-only to other users by only granting the SELECT object privilege to them, but the tables remained read-write for the owner.• Oracle 11g allows tables to be marked as read-only using the ALTER TABLE command.ALTER TABLE table_name READ ONLY;ALTER TABLE table_name READ WRITE;
  23. 23. New Featues for Developers & DBAs INVISIBLE indexes• An invisible index is invisible to the optimizer as default.• Using this feature we can test a new index without effecting the execution plans of the existing sql statements or we can test the effect of dropping an index without dropping it.• They are ignored by the optimizer unless the OPTIMIZER_USE_INVISIBLE_INDEXES parameter is set to TRUE at the instance or session level.CREATE INDEX index_name ON table_name(column_name) INVISIBLE;ALTER INDEX index_name INVISIBLE;ALTER INDEX index_name VISIBLE;
  24. 24. New Featues for Developers & DBAs SQL_monitoringOracle 11g automatically monitors SQL statements if they are run in parallel, or consume 5 or more seconds of CPU or I/O in a single execution.This allows resource intensive SQL to be monitored as it is executing, as well as giving access to detailed information about queries once they arecomplete.
  25. 25. New Features for Developers & DBAs History Tables & Enterprise ManagerWith history tables DBA can query historical performance data to solve problems . Enterprise Manager can help DBAs to probe problems.Some important history tables• DBA_HIST_ACTIVE_SESS_HISTORY• DBA_HIST_SQLSTAT• DBA_HIST_SQLTEXT• DBA_HIST_SQL_PLAN• DBA_HIST_SYSSTAT• DBA_HIST_WAITSTAT
  26. 26. PL/SQL New Features Referenceshttp://docs.oracle.com/cd/E11882_01/appdev.112/e25519/toc.htmhttp://docs.oracle.com/cd/E11882_01/appdev.112/e25519/tuning.htm#CHDJJAGH

×