6 Şubat 2013 Çarşamba

[Oracle] - Existence check ve performansları


Merhabalar,

Oracle geliştirmeleri yaparken en az bir kez kullandığımız ”existence check (Bir data mevcut mu kontrolü)” yöntemlerini ve performans farkları ile ilgili bir test yaptım ve sizle paylaşmak istedim.

Not: 5. Yöntemde explicit cursor kullanılıyor. Her ne kadar bu örnek için çok farklı performans vermiyor olsa da ilk 4 yöntemde olduğu gibi implicit cursor kullanmak her zaman tercih edilmelidir. Detaylar için aşağıdaki linkler incelenebilir:



create table TABLE_TEST
(
  key   NUMBER,
  value VARCHAR2(2)
);


INSERT INTO table_test
  SELECT LEVEL
        ,dbms_random.string('X',
                            2)
  FROM   dual
  CONNECT BY LEVEL <= 10000;

COMMIT;


DECLARE
  l_start PLS_INTEGER;
  l_end   PLS_INTEGER;

  l_count PLS_INTEGER;

  CURSOR yontem5 IS
    SELECT 1
    FROM   table_test t
    WHERE  t.value = 'AA';

BEGIN

  --Yontem 1

  l_start := dbms_utility.get_time;

  FOR i IN 1 .. 5000 LOOP
 
    SELECT COUNT(1)
    INTO   l_count
    FROM   table_test t
    WHERE  t.value = 'AA';
 
    IF l_count > 0 THEN
      NULL;
    ELSE
      NULL;
    END IF;
 
  END LOOP;

  l_end := dbms_utility.get_time;

  dbms_output.put_line('Yontem 1 sonucu: ' || to_char(l_end - l_start));

  --Yontem 2
  l_start := dbms_utility.get_time;

  FOR i IN 1 .. 5000 LOOP
 
    SELECT COUNT(1)
    INTO   l_count
    FROM   dual
    WHERE  EXISTS (SELECT 1
            FROM   table_test t
            WHERE  t.value = 'AA');
 
    IF l_count > 0 THEN
      NULL;
    ELSE
      NULL;
    END IF;
 
  END LOOP;
  l_end := dbms_utility.get_time;

  dbms_output.put_line('Yontem 2 sonucu: ' || to_char(l_end - l_start));

  --Yontem 3

  l_start := dbms_utility.get_time;

  FOR i IN 1 .. 5000 LOOP
 
    SELECT COUNT(1)
    INTO   l_count
    FROM   (SELECT 1
            FROM   table_test t
            WHERE  t.value = 'AA'
            AND    rownum = 1);
 
    IF l_count > 0 THEN
      NULL;
    ELSE
      NULL;
    END IF;
 
  END LOOP;
  l_end := dbms_utility.get_time;

  dbms_output.put_line('Yontem 3 sonucu: ' || to_char(l_end - l_start));

  --Yontem 4

  l_start := dbms_utility.get_time;

  FOR i IN 1 .. 5000 LOOP
 
    SELECT CASE
             WHEN EXISTS (SELECT 1
                   FROM   table_test t
                   WHERE  t.value = 'AA') THEN
              1
             ELSE
              0
           END AS rec_exists
    INTO   l_count
    FROM   dual;
 
    IF l_count > 0 THEN
      NULL;
    ELSE
      NULL;
    END IF;
 
  END LOOP;
  l_end := dbms_utility.get_time;

  dbms_output.put_line('Yontem 4 sonucu: ' || to_char(l_end - l_start));

  --Yontem 5
  l_start := dbms_utility.get_time;

  FOR i IN 1 .. 5000 LOOP
 
    OPEN yontem5;
 
    FETCH yontem5
      INTO l_count;
 
    IF yontem5%FOUND THEN
      NULL;
    ELSE
      NULL;
    END IF;
    CLOSE yontem5;
  END LOOP;

  l_end := dbms_utility.get_time;

  dbms_output.put_line('Yontem 5 sonucu: ' || to_char(l_end - l_start));
END;


Yontem 1 sonucu: 151
Yontem 2 sonucu: 51
Yontem 3 sonucu: 50
Yontem 4 sonucu: 49
Yontem 5 sonucu: 50

Hiç yorum yok:

Yorum Gönder