Blog programisty w Oracle PL/SQL

Jest to blog eksperymentatora programisty w PL/SQL dla Oracle. Wszystkie kody tutaj zamieszczone mogą być dowolnie wykorzystywane i zmieniane. A jeśli Ktoś z Gości znajdzie błąd, będę niezwykle wdzięczny...
Zapisz

Szukaj na tym blogu

poniedziałek, 26 października 2015

Jeden parametr sekwencji a wydajność przy wstawianiu

Sekwencja zapewnia unikalność identyfikatorów, ale nie ich ciągłość na zbiorze liczb całkowitych.  W zależności od liczby wstawianych rekordów warto buforować w pamięci kolejne wartości sekwencji, zwłaszcza przy masowym wstawianiu. Stwórzmy sekwencję
CREATE SEQUENCE SEQ_START START WITHCACHE 2;
oraz prostą tabelę, gdzie w polu ID będziemy wstawiać kolejne wartości sekwencji
CREATE TABLE TBL_TEST
(
 ID NUMBER NOT NULL,
 DESCRIPTION_1 VARCHAR2(40 CHAR) NOT NULL,
 DESCRIPTION_2 VARCHAR2(40 CHAR) NOT NULL,
 DESCRIPTION_3 VARCHAR2(40 CHAR) NOT NULL
);

Poniższy blok wstawia do pustej tabeli  sto tysięcy rekordów bez korzystania z sekwencji. Uśredniony czas wykonania to 4,3 sekundy..
DECLARE
    vn_Start NUMBER;
BEGIN
  EXECUTE IMMEDIATE
  'TRUNCATE TABLE TBL_TEST'
;
  vn_Start := dbms_utility.get_time;
  
  FOR EL IN  1..100000
   LOOP
       INSERT INTO ALTAIRDB.TBL_TEST (
        ID, DESCRIPTION_1, DESCRIPTION_2,
        DESCRIPTION_3)
    VALUES (  EL /* ID */,
        'DESCRPTION_1 ' || EL /* DESCRIPTION_1 */,
        'DESCRPTION_2 ' || EL /* DESCRIPTION_2 */,
        'DESCRPTION_3 ' || EL /* DESCRIPTION_3 */ );
   END LOOP;
   COMMIT;
dbms_output.put_line( ROUND( (dbms_utility.get_time- vn_start)/100, 2 ) || ' sekund...' );
END;

W poniższym przykładzie wstawiamy wielokrotnie do pustej tabeli po  sto tysięcy rekordów z wykorzystaniem sekwencji z różnym parametrem buforowania.
DECLARE.
vn_Start NUMBER;
BEGIN
  FOR
EL_OUT IN (SELECT COLUMN_VALUE AS CACHE_SIZE,
                    DECODE( COLUMN_VALUE, 1 , 'NOCACHE', 'CACHE ' || COLUMN_VALUE)   AS CACHE_DDL
                 FROM TABLE(SYS.ODCINUMBERLIST(1, 2,5,10, 20, 50, 100, 500, 1000, 5000, 10000))) 
  LOOP
    BEGIN
        EXECUTE IMMEDIATE
'DROP SEQUENCE SEQ_START'
;
    EXCEPTION WHEN OTHERS THEN
        NULL
;   
    END;
  EXECUTE IMMEDIATE 'TRUNCATE TABLE TBL_TEST';
  EXECUTE IMMEDIATE 'CREATE SEQUENCE SEQ_START START WITH 1 ' || EL_OUT.CACHE_DDL;
  vn_Start := dbms_utility.get_time;
    FOR EL_IN IN  1..100000
       LOOP
           INSERT INTO
TBL_TEST (
            ID, DESCRIPTION_1, DESCRIPTION_2,
            DESCRIPTION_3)
        VALUES (  SEQ_START.nextval /* ID */,
            'DESCRPTION_1 ' || EL_IN /* DESCRIPTION_1 */,
            'DESCRPTION_2 ' || EL_IN /* DESCRIPTION_2 */,
            'DESCRPTION_3 ' || EL_IN /* DESCRIPTION_3 */ );
       END LOOP;
    COMMIT;
  dbms_output.put_line( EL_OUT.CACHE_DDL || ' - ' || ROUND( (dbms_utility.get_time- vn_start)/100, 2 ) || ' sekund...' );
  END LOOP;
END;

Wyniki:
NOCACHE - 26,9 sekund...
CACHE 2 - 17,82 sekund...
CACHE 5 - 10,82 sekund...
CACHE 10 - 8,78 sekund...
CACHE 20 - 7,79 sekund...
CACHE 50 - 7,17 sekund...
CACHE 100 - 7,01 sekund...
CACHE 500 - 6,94 sekund...
CACHE 1000 - 6,95 sekund...
CACHE 5000 - 6,87 sekund...
CACHE 10000 - 6,56 sekund...

To jest przykład na to, jak mało ważne  parametry mogą istotnie zmniejszyć wydajność,zwłaszcza dla masowego przetwarzania...

Brak komentarzy:

Prześlij komentarz