Özet: Sorgularda neden “bind” kullanılması gerekiyor, direkt değer(literal) girilmesinden neden kaçınmak gerekiyor örneklerle anlatılıyor.

Oracle veritabanı, shared pool da olmayan ilk kez çalıştırılan sorgu için execution plan oluşturur, bu esnada sorgunun yazılışını, sentaksını, doğruluğunu kontrol eder ve yoğun CPU harcar, bu işleme hard parse denir.

Eğer sorgumuz shared pool’da varsa direkt mevcut execution planını kullanacak ve “execution time” süresi kısalacaktır. “Bind” kullanımı ile bunu gerçekleştirebiliyoruz.  Aşağıdaki örnekteki gibi DML’lerimizde bind kullanılırsa, maliyeti (cost) oldukça düşürecek ve çok daha hızlı sonuç alınacaktır.

Bind’sız kullanım: Bu kullanımda aşağıdaki gibi direkt olarak değer atıyoruz:

select id,str1,str2 from test where id = 10;

Bind’lı kullanım: Bu kullanımda ise aşağıdaki gibi değeri değişken(:v_id) üzerinden atıyoruz:

select id,str1,str2 from test where id = :v_id;

Aşağıdaki örnek ile “execution time” (çalışma süresi) karşılaştırması yaptığımızda bind’lı kullanımda çok daha kısa sürede sonuç alabildiğimizi görebiliriz;

create table test(
 id number, str1 varchar2(200), str2 varchar2(200)
 );

Bind’sız kullanım:

declare
 cursor c is select object_id, object_name, owner
 from all_objects where rownum <= 5000;
 startTime number(20);
 sqlStr varchar2(200);
begin
 startTime := dbms_utility.get_time;
  for i in c loop
 sqlStr := 'insert into test values(' || i.object_id || ',''' || i.object_name || ''',''' || i.owner || ''')';
 execute immediate sqlStr;
  end loop;
 commit;
 dbms_output.put_line('Bind''sız kullanımda geçen süre : ' || (dbms_utility.get_time - startTime) );
end;

* Bind’sız kullanımda geçen süre : 288 ms

Bind’lı kullanım:

truncate table test;
declare
 cursor c is select object_id, object_name, owner
 from all_objects where rownum <= 5000;
 startTime number(20);
 sqlStr varchar2(200);
begin
 startTime := dbms_utility.get_time;
  for i in c loop
 execute immediate 'insert into test values(:x,:y,:z)'
 using i.object_id,i.object_name, i.owner;
  end loop;
 commit;
 dbms_output.put_line('Bind''lı kullanımda geçen süre: ' || (dbms_utility.get_time - startTime));
end;

* Bind’lı kullanımda geçen süre: 10 ms

 drop table test;