SlideShare une entreprise Scribd logo
1  sur  26
Télécharger pour lire hors ligne
Agenda

Oracle 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
Row-by-Row Processing
DO NOT USE                                                                 USE
DECLARE                                                                    --
CURSOR c1 IS                                                               -- Insert in to target table
SELECT 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 c
INSERT 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
Nested Row-by-Row Processing
DO NOT USE                                                                 USE


DECLARE                                                                    MERGE INTO fact1 USING
CURSOR c1 AS                                                               (SELECT DISTINCT c3.n1,c3.n2
   SELECT n1 FROM t1;                                                      FROM t1, t2, t3
CURSOR c2 (p_n1) AS                                                        WHERE t1.n1 = t2.n1
   SELECT n1, n2 FROM t2 WHERE n1=p_n1;                                    AND t2.n1 = t3.n1
CURSOR 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 THEN
FOR c1_rec IN c1                                                             UPDATE SET .. WHEN NOT matched THEN
LOOP                                                                         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.
Lookup Queries
DO NOT USE                                                                    USE
                                                                              DECLARE
DECLARE                                                                        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_type
BEGIN                                                                          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.
Result Cache for Lookup Queries
DO NOT USE                                                                   USE
                                                                             DECLARE
DECLARE                                                                       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;                                 BEGIN
BEGIN                                                                         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.
Excessive Access to DUAL
DO NOT USE                                                              USE


DECLARE                                                                 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.
Excessive Access to DUAL
DO NOT USE                                                              USE


DECLARE
 l_cust_id NUMBER;                                                         INSERT INTO customers_hist
BEGIN                                                                        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.
Populating Master-Detail Rows
DO NOT USE                                                               USE


DECLARE
 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 in
to the detail table.
Unnecessary Function Execution
DO NOT USE                                                                   USE
CREATE TABLE log_table (message_seq NUMBER, MESSAGE VARCHAR2 (512));
                                                                             DECLARE
CREATE 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.
Unnecessary Function Execution
DO NOT USE                                                                  USE
CREATE 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;                                                           SELECT
BEGIN                                                                          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 s
WHERE 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 function
execution, you avoid unneeded flushing and refilling of the instruction pipeline, thus minimizing demands upon your CPU.
Unnecessary Function Execution
DO NOT USE                                                                USE
CREATE 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)) epoch
END 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 s
WHERE 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 queries
into memory . A result cache shareable and is stored in SGA memory
Database Link Calls
DO NOT USE                                                                 USE

DECLARE
V_customer_name VARCHAR2(32);                                              CREATE MATERIALIZED VIEW customers_snapshot
BEGIN                                                                      ...
...                                                                        AS
FOR 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 a
loop is not a scalable approach. For each access to a remote table, several SQL*Net packets are exchanged between the databases involved in the
database link.
Excessive Parsing
DO NOT USE                                                                    USE


DECLARE                                                                       DECLARE
...                                                                           ...
BEGIN                                                                         BEGIN
FOR c1_rec IN c1                                                              FOR c1_rec IN c1
LOOP                                                                          LOOP
-- Query customer details                                                     -- Query customer details
EXECUTE IMMEDIATE
'SELECT cust_first_name, cust_last_name, country_id
FROM customers                                                                SELECT cust_first_name, cust_last_name, country_id into
WHERE 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 the
application’s scalability and concurrency.
Excessive Commits
DO NOT USE                                                                   USE
                                                                             DECLARE
DECLARE                                                                      commit_number pls_integer;
BEGIN
                                                                             BEGIN
FOR c1_rec IN c1                                                             commit_number := 0;
LOOP
                                                                             FOR c1_rec IN c1
                                                                             LOOP
-- Query customer details
                                                                             -- Query customer details
SELECT 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;                                                                     Then
END 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, and
consume more resources.
Type Usage in Spec Definetions
DO NOT USE                                                                 USE


CREATE OR REPLACE PACKAGE check_bilgi                                      CREATE OR REPLACE PACKAGE check_bilgi
IS                                                                         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 .
PL/SQL New Features
                               SIMPLE_INTEGER Datatype
The SIMPLE_INTEGER datatype is a subtype of the PLS_INTEGER datatype and can dramatical increase the speed of integer arithmetic

CREATE 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;
/
PL/SQL New Features
                                           Continue Statement
The 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 statement

DECLARE
 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;
/
PL/SQL New Features
                                     Sequences in PL/SQL expressions
The 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;
BEGIN

FOR 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;
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;
/
PL/SQL New Features
                                 Automatic Subprogram Inlining
Automatic subprogram inlining replace the subprogram calls with a copy of the code in the subprogram at compile time.
Reduce the overheads associated with calling subprograms

ALTER 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;
/
PL/SQL New Features
                                              Native Compilation

In 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 code
and 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_SETTINGS
views 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.
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;
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;
New Featues for Developers & DBAs
                                                   SQL_monitoring

Oracle 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 are
complete.
New Features for Developers & DBAs
                       History Tables & Enterprise Manager
With 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
PL/SQL New Features
                                  References

http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/toc.htm

http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/tuning.htm#CHDJJAGH

Contenu connexe

Tendances

Oracle - Program with PL/SQL - Lession 16
Oracle - Program with PL/SQL - Lession 16Oracle - Program with PL/SQL - Lession 16
Oracle - Program with PL/SQL - Lession 16Thuan Nguyen
 
ORACLE PL SQL FOR BEGINNERS
ORACLE PL SQL FOR BEGINNERSORACLE PL SQL FOR BEGINNERS
ORACLE PL SQL FOR BEGINNERSmohdoracle
 
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...Michael Rosenblum
 
Oracle - Program with PL/SQL - Lession 07
Oracle - Program with PL/SQL - Lession 07Oracle - Program with PL/SQL - Lession 07
Oracle - Program with PL/SQL - Lession 07Thuan Nguyen
 
Programming in Oracle with PL/SQL
Programming in Oracle with PL/SQLProgramming in Oracle with PL/SQL
Programming in Oracle with PL/SQLlubna19
 
Oracle - Program with PL/SQL - Lession 03
Oracle - Program with PL/SQL - Lession 03Oracle - Program with PL/SQL - Lession 03
Oracle - Program with PL/SQL - Lession 03Thuan Nguyen
 
Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01Thuan Nguyen
 
Oracle - Program with PL/SQL - Lession 09
Oracle - Program with PL/SQL - Lession 09Oracle - Program with PL/SQL - Lession 09
Oracle - Program with PL/SQL - Lession 09Thuan Nguyen
 
Oracle - Program with PL/SQL - Lession 06
Oracle - Program with PL/SQL - Lession 06Oracle - Program with PL/SQL - Lession 06
Oracle - Program with PL/SQL - Lession 06Thuan Nguyen
 
Basic cursors in oracle
Basic cursors in oracleBasic cursors in oracle
Basic cursors in oracleSuhel Firdus
 
Developer's Approach to Code Management
Developer's Approach to Code ManagementDeveloper's Approach to Code Management
Developer's Approach to Code ManagementMichael Rosenblum
 
Trigger and cursor program using sql
Trigger and cursor program using sqlTrigger and cursor program using sql
Trigger and cursor program using sqlSushil Mishra
 
Procedures/functions of rdbms
Procedures/functions of rdbmsProcedures/functions of rdbms
Procedures/functions of rdbmsjain.pralabh
 
Firebird 3 Windows Functions
Firebird 3 Windows  FunctionsFirebird 3 Windows  Functions
Firebird 3 Windows FunctionsMind The Firebird
 
Oracle - Program with PL/SQL - Lession 04
Oracle - Program with PL/SQL - Lession 04Oracle - Program with PL/SQL - Lession 04
Oracle - Program with PL/SQL - Lession 04Thuan Nguyen
 

Tendances (20)

Oracle - Program with PL/SQL - Lession 16
Oracle - Program with PL/SQL - Lession 16Oracle - Program with PL/SQL - Lession 16
Oracle - Program with PL/SQL - Lession 16
 
Plsql
PlsqlPlsql
Plsql
 
ORACLE PL SQL FOR BEGINNERS
ORACLE PL SQL FOR BEGINNERSORACLE PL SQL FOR BEGINNERS
ORACLE PL SQL FOR BEGINNERS
 
Oracle: Procedures
Oracle: ProceduresOracle: Procedures
Oracle: Procedures
 
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
Hidden Gems of Performance Tuning: Hierarchical Profiler and DML Trigger Opti...
 
Oracle - Program with PL/SQL - Lession 07
Oracle - Program with PL/SQL - Lession 07Oracle - Program with PL/SQL - Lession 07
Oracle - Program with PL/SQL - Lession 07
 
Programming in Oracle with PL/SQL
Programming in Oracle with PL/SQLProgramming in Oracle with PL/SQL
Programming in Oracle with PL/SQL
 
Oracle - Program with PL/SQL - Lession 03
Oracle - Program with PL/SQL - Lession 03Oracle - Program with PL/SQL - Lession 03
Oracle - Program with PL/SQL - Lession 03
 
Stored procedure
Stored procedureStored procedure
Stored procedure
 
PLSQL Advanced
PLSQL AdvancedPLSQL Advanced
PLSQL Advanced
 
Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01
 
Oracle - Program with PL/SQL - Lession 09
Oracle - Program with PL/SQL - Lession 09Oracle - Program with PL/SQL - Lession 09
Oracle - Program with PL/SQL - Lession 09
 
Oracle - Program with PL/SQL - Lession 06
Oracle - Program with PL/SQL - Lession 06Oracle - Program with PL/SQL - Lession 06
Oracle - Program with PL/SQL - Lession 06
 
Basic cursors in oracle
Basic cursors in oracleBasic cursors in oracle
Basic cursors in oracle
 
Developer's Approach to Code Management
Developer's Approach to Code ManagementDeveloper's Approach to Code Management
Developer's Approach to Code Management
 
Trigger and cursor program using sql
Trigger and cursor program using sqlTrigger and cursor program using sql
Trigger and cursor program using sql
 
Procedures/functions of rdbms
Procedures/functions of rdbmsProcedures/functions of rdbms
Procedures/functions of rdbms
 
Firebird 3 Windows Functions
Firebird 3 Windows  FunctionsFirebird 3 Windows  Functions
Firebird 3 Windows Functions
 
Oracle - Program with PL/SQL - Lession 04
Oracle - Program with PL/SQL - Lession 04Oracle - Program with PL/SQL - Lession 04
Oracle - Program with PL/SQL - Lession 04
 
Cursors
CursorsCursors
Cursors
 

En vedette

Take Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL CompilerTake Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL CompilerSteven Feuerstein
 
PL/SQL Fundamentals I
PL/SQL Fundamentals IPL/SQL Fundamentals I
PL/SQL Fundamentals INick Buytaert
 
1 - Introduction to PL/SQL
1 - Introduction to PL/SQL1 - Introduction to PL/SQL
1 - Introduction to PL/SQLrehaniltifat
 
PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts Bharat Kalia
 
04 Handling Exceptions
04 Handling Exceptions04 Handling Exceptions
04 Handling Exceptionsrehaniltifat
 
Cooper Oracle 11g Overview
Cooper Oracle 11g OverviewCooper Oracle 11g Overview
Cooper Oracle 11g Overviewmoin_azeem
 
Oracle Database Overview
Oracle Database OverviewOracle Database Overview
Oracle Database Overviewhonglee71
 
A must Sql notes for beginners
A must Sql notes for beginnersA must Sql notes for beginners
A must Sql notes for beginnersRam Sagar Mourya
 
[Oracle数据库11 g初学者指南].oracle.database.11g,.a.beginner's.guide
[Oracle数据库11 g初学者指南].oracle.database.11g,.a.beginner's.guide[Oracle数据库11 g初学者指南].oracle.database.11g,.a.beginner's.guide
[Oracle数据库11 g初学者指南].oracle.database.11g,.a.beginner's.guidegavin shaw
 
Interacting with Oracle Database
Interacting with Oracle DatabaseInteracting with Oracle Database
Interacting with Oracle DatabaseChhom Karath
 
PL/SQL Complete Tutorial. All Topics Covered
PL/SQL Complete Tutorial. All Topics CoveredPL/SQL Complete Tutorial. All Topics Covered
PL/SQL Complete Tutorial. All Topics CoveredDanish Mehraj
 
Database Development Mistakes
Database Development MistakesDatabase Development Mistakes
Database Development MistakesMichael Findling
 
Why is the application running so slowly?
Why is the application running so slowly?Why is the application running so slowly?
Why is the application running so slowly?Michael Rosenblum
 
3963066 pl-sql-notes-only
3963066 pl-sql-notes-only3963066 pl-sql-notes-only
3963066 pl-sql-notes-onlyAshwin Kumar
 
A green solution to solve a race condition problem
A green solution to solve a race condition problemA green solution to solve a race condition problem
A green solution to solve a race condition problemKai Zhou
 

En vedette (20)

Take Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL CompilerTake Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL Compiler
 
PL/SQL Fundamentals I
PL/SQL Fundamentals IPL/SQL Fundamentals I
PL/SQL Fundamentals I
 
Best sql plsql material
Best sql plsql materialBest sql plsql material
Best sql plsql material
 
1 - Introduction to PL/SQL
1 - Introduction to PL/SQL1 - Introduction to PL/SQL
1 - Introduction to PL/SQL
 
PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts
 
04 Handling Exceptions
04 Handling Exceptions04 Handling Exceptions
04 Handling Exceptions
 
Cooper Oracle 11g Overview
Cooper Oracle 11g OverviewCooper Oracle 11g Overview
Cooper Oracle 11g Overview
 
Dbms viva questions
Dbms viva questionsDbms viva questions
Dbms viva questions
 
DBMS Practical File
DBMS Practical FileDBMS Practical File
DBMS Practical File
 
Oracle Database Overview
Oracle Database OverviewOracle Database Overview
Oracle Database Overview
 
A must Sql notes for beginners
A must Sql notes for beginnersA must Sql notes for beginners
A must Sql notes for beginners
 
[Oracle数据库11 g初学者指南].oracle.database.11g,.a.beginner's.guide
[Oracle数据库11 g初学者指南].oracle.database.11g,.a.beginner's.guide[Oracle数据库11 g初学者指南].oracle.database.11g,.a.beginner's.guide
[Oracle数据库11 g初学者指南].oracle.database.11g,.a.beginner's.guide
 
Interacting with Oracle Database
Interacting with Oracle DatabaseInteracting with Oracle Database
Interacting with Oracle Database
 
PL/SQL Complete Tutorial. All Topics Covered
PL/SQL Complete Tutorial. All Topics CoveredPL/SQL Complete Tutorial. All Topics Covered
PL/SQL Complete Tutorial. All Topics Covered
 
Views Oracle Database
Views Oracle DatabaseViews Oracle Database
Views Oracle Database
 
Les01
Les01Les01
Les01
 
Database Development Mistakes
Database Development MistakesDatabase Development Mistakes
Database Development Mistakes
 
Why is the application running so slowly?
Why is the application running so slowly?Why is the application running so slowly?
Why is the application running so slowly?
 
3963066 pl-sql-notes-only
3963066 pl-sql-notes-only3963066 pl-sql-notes-only
3963066 pl-sql-notes-only
 
A green solution to solve a race condition problem
A green solution to solve a race condition problemA green solution to solve a race condition problem
A green solution to solve a race condition problem
 

Similaire à Oracle 11g PL/SQL notes

Function Procedure Trigger Partition.pdf
Function Procedure Trigger Partition.pdfFunction Procedure Trigger Partition.pdf
Function Procedure Trigger Partition.pdfSanam Maharjan
 
PostgreSQL Portland Performance Practice Project - Database Test 2 Workload D...
PostgreSQL Portland Performance Practice Project - Database Test 2 Workload D...PostgreSQL Portland Performance Practice Project - Database Test 2 Workload D...
PostgreSQL Portland Performance Practice Project - Database Test 2 Workload D...Mark Wong
 
MySQL Stored Procedures: Building High Performance Web Applications
MySQL Stored Procedures: Building High Performance Web ApplicationsMySQL Stored Procedures: Building High Performance Web Applications
MySQL Stored Procedures: Building High Performance Web ApplicationsOSSCube
 
Open Gurukul Language PL/SQL
Open Gurukul Language PL/SQLOpen Gurukul Language PL/SQL
Open Gurukul Language PL/SQLOpen Gurukul
 
Query Optimizer: further down the rabbit hole
Query Optimizer: further down the rabbit holeQuery Optimizer: further down the rabbit hole
Query Optimizer: further down the rabbit holeMariaDB plc
 
MariaDB Optimizer - further down the rabbit hole
MariaDB Optimizer - further down the rabbit holeMariaDB Optimizer - further down the rabbit hole
MariaDB Optimizer - further down the rabbit holeSergey Petrunya
 
How to transfer bad PLSQL into good (AAAPEKS23)
How to transfer bad PLSQL into good (AAAPEKS23)How to transfer bad PLSQL into good (AAAPEKS23)
How to transfer bad PLSQL into good (AAAPEKS23)Maik Becker
 
解决Ora 14098分区交换索引不匹配错误
解决Ora 14098分区交换索引不匹配错误解决Ora 14098分区交换索引不匹配错误
解决Ora 14098分区交换索引不匹配错误maclean liu
 
Unit 3(rdbms)
Unit 3(rdbms)Unit 3(rdbms)
Unit 3(rdbms)Jay Patel
 
Unit 3(rdbms)
Unit 3(rdbms)Unit 3(rdbms)
Unit 3(rdbms)Jay Patel
 
ADBMS ASSIGNMENT
ADBMS ASSIGNMENTADBMS ASSIGNMENT
ADBMS ASSIGNMENTLori Moore
 
PL/SQL Code for Sample Projects
PL/SQL Code for Sample ProjectsPL/SQL Code for Sample Projects
PL/SQL Code for Sample Projectsjwjablonski
 
PL/SQL & SQL CODING GUIDELINES – Part 5
PL/SQL & SQL CODING GUIDELINES – Part 5PL/SQL & SQL CODING GUIDELINES – Part 5
PL/SQL & SQL CODING GUIDELINES – Part 5Larry Nung
 

Similaire à Oracle 11g PL/SQL notes (20)

Function Procedure Trigger Partition.pdf
Function Procedure Trigger Partition.pdfFunction Procedure Trigger Partition.pdf
Function Procedure Trigger Partition.pdf
 
Pl sql guide
Pl sql guidePl sql guide
Pl sql guide
 
PostgreSQL Portland Performance Practice Project - Database Test 2 Workload D...
PostgreSQL Portland Performance Practice Project - Database Test 2 Workload D...PostgreSQL Portland Performance Practice Project - Database Test 2 Workload D...
PostgreSQL Portland Performance Practice Project - Database Test 2 Workload D...
 
MySQL Stored Procedures: Building High Performance Web Applications
MySQL Stored Procedures: Building High Performance Web ApplicationsMySQL Stored Procedures: Building High Performance Web Applications
MySQL Stored Procedures: Building High Performance Web Applications
 
Open Gurukul Language PL/SQL
Open Gurukul Language PL/SQLOpen Gurukul Language PL/SQL
Open Gurukul Language PL/SQL
 
Query Optimizer: further down the rabbit hole
Query Optimizer: further down the rabbit holeQuery Optimizer: further down the rabbit hole
Query Optimizer: further down the rabbit hole
 
MariaDB Optimizer - further down the rabbit hole
MariaDB Optimizer - further down the rabbit holeMariaDB Optimizer - further down the rabbit hole
MariaDB Optimizer - further down the rabbit hole
 
How to transfer bad PLSQL into good (AAAPEKS23)
How to transfer bad PLSQL into good (AAAPEKS23)How to transfer bad PLSQL into good (AAAPEKS23)
How to transfer bad PLSQL into good (AAAPEKS23)
 
解决Ora 14098分区交换索引不匹配错误
解决Ora 14098分区交换索引不匹配错误解决Ora 14098分区交换索引不匹配错误
解决Ora 14098分区交换索引不匹配错误
 
stored.ppt
stored.pptstored.ppt
stored.ppt
 
Unit 3(rdbms)
Unit 3(rdbms)Unit 3(rdbms)
Unit 3(rdbms)
 
Unit 3(rdbms)
Unit 3(rdbms)Unit 3(rdbms)
Unit 3(rdbms)
 
ADBMS ASSIGNMENT
ADBMS ASSIGNMENTADBMS ASSIGNMENT
ADBMS ASSIGNMENT
 
PL/SQL Code for Sample Projects
PL/SQL Code for Sample ProjectsPL/SQL Code for Sample Projects
PL/SQL Code for Sample Projects
 
Cdc
CdcCdc
Cdc
 
C++
C++C++
C++
 
Introduction to mysql part 3
Introduction to mysql part 3Introduction to mysql part 3
Introduction to mysql part 3
 
PL/SQL & SQL CODING GUIDELINES – Part 5
PL/SQL & SQL CODING GUIDELINES – Part 5PL/SQL & SQL CODING GUIDELINES – Part 5
PL/SQL & SQL CODING GUIDELINES – Part 5
 
SQL- Introduction to PL/SQL
SQL- Introduction to  PL/SQLSQL- Introduction to  PL/SQL
SQL- Introduction to PL/SQL
 
DOODB_LAB.pptx
DOODB_LAB.pptxDOODB_LAB.pptx
DOODB_LAB.pptx
 

Dernier

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 

Dernier (20)

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

Oracle 11g PL/SQL notes

  • 1. Agenda Oracle 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. Row-by-Row Processing DO NOT USE USE DECLARE -- CURSOR c1 IS -- Insert in to target table SELECT 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 c INSERT 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. Nested Row-by-Row Processing DO NOT USE USE DECLARE MERGE INTO fact1 USING CURSOR c1 AS (SELECT DISTINCT c3.n1,c3.n2 SELECT n1 FROM t1; FROM t1, t2, t3 CURSOR c2 (p_n1) AS WHERE t1.n1 = t2.n1 SELECT n1, n2 FROM t2 WHERE n1=p_n1; AND t2.n1 = t3.n1 CURSOR 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 THEN FOR c1_rec IN c1 UPDATE SET .. WHEN NOT matched THEN LOOP 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. Lookup Queries DO NOT USE USE DECLARE DECLARE 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_type BEGIN 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. Result Cache for Lookup Queries DO NOT USE USE DECLARE DECLARE 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; BEGIN BEGIN 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. Excessive Access to DUAL DO NOT USE USE DECLARE 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. Excessive Access to DUAL DO NOT USE USE DECLARE l_cust_id NUMBER; INSERT INTO customers_hist BEGIN 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. Populating Master-Detail Rows DO NOT USE USE DECLARE 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 in to the detail table.
  • 9. Unnecessary Function Execution DO NOT USE USE CREATE TABLE log_table (message_seq NUMBER, MESSAGE VARCHAR2 (512)); DECLARE CREATE 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. Unnecessary Function Execution DO NOT USE USE CREATE 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; SELECT BEGIN 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 s WHERE 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 function execution, you avoid unneeded flushing and refilling of the instruction pipeline, thus minimizing demands upon your CPU.
  • 11. Unnecessary Function Execution DO NOT USE USE CREATE 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)) epoch END 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 s WHERE 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 queries into memory . A result cache shareable and is stored in SGA memory
  • 12. Database Link Calls DO NOT USE USE DECLARE V_customer_name VARCHAR2(32); CREATE MATERIALIZED VIEW customers_snapshot BEGIN ... ... AS FOR 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 a loop is not a scalable approach. For each access to a remote table, several SQL*Net packets are exchanged between the databases involved in the database link.
  • 13. Excessive Parsing DO NOT USE USE DECLARE DECLARE ... ... BEGIN BEGIN FOR c1_rec IN c1 FOR c1_rec IN c1 LOOP LOOP -- Query customer details -- Query customer details EXECUTE IMMEDIATE 'SELECT cust_first_name, cust_last_name, country_id FROM customers SELECT cust_first_name, cust_last_name, country_id into WHERE 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 the application’s scalability and concurrency.
  • 14. Excessive Commits DO NOT USE USE DECLARE DECLARE commit_number pls_integer; BEGIN BEGIN FOR c1_rec IN c1 commit_number := 0; LOOP FOR c1_rec IN c1 LOOP -- Query customer details -- Query customer details SELECT 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; Then END 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, and consume more resources.
  • 15. Type Usage in Spec Definetions DO NOT USE USE CREATE OR REPLACE PACKAGE check_bilgi CREATE OR REPLACE PACKAGE check_bilgi IS 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. PL/SQL New Features SIMPLE_INTEGER Datatype The SIMPLE_INTEGER datatype is a subtype of the PLS_INTEGER datatype and can dramatical increase the speed of integer arithmetic CREATE 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. PL/SQL New Features Continue Statement The 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 statement DECLARE 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. PL/SQL New Features Sequences in PL/SQL expressions The 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; BEGIN FOR 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. 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. PL/SQL New Features Automatic Subprogram Inlining Automatic subprogram inlining replace the subprogram calls with a copy of the code in the subprogram at compile time. Reduce the overheads associated with calling subprograms ALTER 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. PL/SQL New Features Native Compilation In 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 code and 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_SETTINGS views 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. 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. 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. New Featues for Developers & DBAs SQL_monitoring Oracle 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 are complete.
  • 25. New Features for Developers & DBAs History Tables & Enterprise Manager With 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. PL/SQL New Features References http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/toc.htm http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/tuning.htm#CHDJJAGH