Eğitim Notları – 2

Pazartesi sabah geldiğimizde departmanlarımıza dağıldık. Benimle birlikte aynı takımda çalışacak olan diğer stajyerlerle birlikte bizler için hazırlanan bilgisayarları kendi isteğimize göre ayarlamaya çalıştık. Çalışmaya başlayabilmek için kurmamız gereken uygulamaları ve erişim haklarımızı, bilgi işlem çalışanları ile birlikte ayarladık ve çalışma ortamımızı hazırlamış olduk.

Aynı gün Fuat Sungur tarafından “Developing Successful Oracle Applications” konulu bir eğitim aldık. Bu eğitimde Oracle üzerinde uygulama geliştirirken dikkat etmemiz gereken noktalar ve problemlere nasıl yaklaşmamız gerektiği üzerine tartıştık. Bu eğitimde aldığım notlar aşağıdaki gibidir:

  • Bind variable kavramı sorguların performansı açısından önemlidir. Bir sorgu yapıldığında, Oracle sorguyu parse etmek, belli bir execution plan oluşturmak gibi işlemler yapar. Bu işlemleri saklar ve aynı sorgu tekrar geldiğinde işlemleri tekrarlamaz. Bu süreç aslında şuna benzer; bir C programını derleyip çalıştırılabilir dosyayı oluşturduğumuzu düşünelim. Çalıştırılabilir dosya oluştuktan sonra kaynak koda ihtiyaç duymadan program tekrar tekrar çalıştırılabilir. Oracle’da benzer şekilde sorguların derlenmiş halini saklar ve tekrar tekrar çalıştırır. Ancak burada bir problem vardır.
SELECT * FROM EMPLOYEES WHERE employeeID = 100;
SELECT * FROM EMPLOYEES WHERE employeeID = 101;

Çok benzer iki sorgu gibi gözüken bu cümleler çalıştırıldığında, her biri ayrı ayrı parse edilir. Çünkü aslında bu iki sorgu, birbirinden farklıdır. Bu da zaman kaybı demektir. Bu zaman kaybını engellemek için, bind variable kullanılır. Aşağıdaki iki örnek, zaman farkının ne kadar fazla olduğunu göstermektedir:

CREATE OR REPLACE PROCEDURE with_binding IS
    TYPE rc IS REF CURSOR;
    l_rc    rc;
    l_dummy all_objects.object_name%TYPE;
    l_start NUMBER DEFAULT dbms_utility.get_time;
BEGIN
    FOR i IN 1 .. 1000 LOOP
        OPEN l_rc FOR 'select object_name from all_objects '  ||
  'where object_id = :X'
        USING i;
        FETCH l_rc
        INTO l_dummy;
        CLOSE l_rc;
    END LOOP;
    dbms_output.put_line(round((dbms_utility.get_time - l_start) / 100, 2)
 || ' seconds...');
END with_binding;
/
CREATE OR REPLACE PROCEDURE without_binding IS
    TYPE rc IS REF CURSOR;
    l_rc    rc;
    l_dummy all_objects.object_name%TYPE;
    l_start NUMBER DEFAULT dbms_utility.get_time;
BEGIN
    FOR i IN 1 .. 1000 LOOP
        OPEN l_rc FOR 'select object_name from all_objects
where object_id = ' || i;
        FETCH l_rc
        INTO l_dummy;
        CLOSE l_rc;
END LOOP;
    dbms_output.put_line(round((dbms_utility.get_time - l_start) / 100, 2)
 || ' seconds...');

END without_binding;

Bu rutinler verildiğinde, aşağıdaki kod çalıştırılabilir. Sonuç, aradaki devasa farkı göstermektedir:

BEGIN
    with_binding;
    without_binding;
END;
----------------------
,05 seconds...
9,86 seconds...
  • Oracle veritabanındaki iki önemli konsept, read-consistent queries ve non-blocking queries olarak bilinir. Read-consistent queries, zamanın belli bir anına göre tutarlı cevaplar döndüren sorgulardır, non-blocking queries ise yazıcılar tarafından engellenmeyen sorguları temsil eder. Yazıcı ve okuyucuların birbirini engellememesi önemlidir. Yazıcılar okuyucuları engellemezse, bir yazma işlemi sürerken veri okunabilir. Okuyucular yazıcıları engellemezse de, bir veri okunurken yazma işlemi yapılabilir. Hem bu özellikleri sağlayıp, hem de veri tutarlılığını sağlamak için, multi-versioning kavramından yararlanılır. t=0 anında bir sorgu isteğinde bulunalım ve bu sorgu t=5 anına kadar sürecek olsun. t=3 anında bir güncelleme isteği, bizim sorgumuzun t<3 iken okuduğu veya t>3 iken okumak istediği veriyi değiştirmek istesin. Eğer yazıcılar okuyucuları beklemez diyorsak, bu mümkün olmalı. Peki bizim sorgumuzun tutarlılığı nasıl sağlanacak? Bu noktada multi-versioning kavramı ortaya çıkıyor. 0<t<5 süresince oluşacak herhangi bir değişiklik, bizim sorgumuzu ilgilendirmemekte. Bizim sorgumuz, her zaman verinin t=0 anındaki haline bakmakta, bu sayede tutarlılık sağlanmaktadır.
  • Kullanılan veritabanının sunduklarını iyi bilmek gerekir. Database Independent bir uygulama geliştireceğim diye, veritabanının kendine özel ama çok faydalı özelliklerini kullanmamak saçma olur. Thomas Kyte’ın sunumundan alıntı yapmak gerekirse, “Problemleri mümkün olduğunca basit bir şekilde ve Oracle’ın sunduğu işlevselliği kullanarak çözün. Bu özellikler için çok para ödediniz.”.

Eğitim Notları – 2” üzerine bir düşünce

  1. Geri bildirim: Eğitim Notları – 4 « Not Defteri

Yorum bırakın