Sühan Erol (Oracle+PHP)

Mart 25, 2009

PHP ile OCI Client Result Cache (Sorgu sonuçlarının İstemci(webserver) tarafında tutulması)

Kategori: Oracle, PHP — suhanerol @ 8:38 pm
Tags:

İstemci tarafında sorgu sonuçlarının tutulması(result caching) Oracle 11g nin sunduğu yeni özelliklerden biridir. Bu özellik OCI (Oracle Call Interface) teknolojisini kullanan uygulamalar ve sürücüler tarafından kullanılabilmektedir. Bu makalede PHP özelinde incelenen konu OCI teknolojisini kullanan diğer programlama lisanlarında da geçerlidir.

İstemci tarafında gerçekleşen bu işlem sayesinde veritabanına bağlantılar azalacağından performans açısından fayda sağlanmaktadır. Sorgu çalıştırılması istemci tarafında yapıldığından sunucuya yük binmeyecek ve sonuç daha hızlı alınacaktır. Sorgu sonuçları istemci tarafında sistem hafızasında(RAM) tutulmaktadır. İstemcide bulunan farklı uygulamalar OCI teknolojilerini kullandıkları takdirde bu özellikten ortak olarak yararlanabilmektedirler. Bir diğer ifadeyle OCI tarafından sağlanan bu sorgu sonuç deposu tüm OCI kullanan uygulamalara saydamdır ve ortak olarak kullanılabilmektedir. Mevcut sorgu sonuçları veritabanında meydana gelen bir değişiklik sonucunda otomatik olarak güncellenmektedir. İstemci peş peşe sorgu dizisi çalıştırdığı esnada veritabanında ilgili kayıtlarda bir değişiklik olursa istemcideki sorgu sonuçları önce geçersiz duruma getirilir daha sonra sorgu sonuncunun son hali depolanır ve kullanılmaya devam eder.

.

İstemci tarafındaki sorgu sonuç deposunun güncel tutulması işlemi veritabanı ve OCI arasındaki iletişim sayesinde yapılmaktadır. Veritabanında ilgili veriler bir transaction tarafından değiştirilmesi durumunda, istemciden yapılacak olan ilk istek sırasında istemciye mevcut sorgu sonucunun geçersiz olduğu bilgisi gönderilir ve bu sorgu sonucunun kullanılması engellenmiş olur. Eğer istemciden veritabanına bir süre istekte bulunulmamışsa ve bu süre CLIENT_RESULT_CACHE_LAG veritabanı parametresinde belirtilen (varsayılan 3 saniye) süreden uzun ise yine OCI bir sonraki oci_execute() işleminin güncellik kontrolü yapmasını sağlayacaktır.

Bu özelliğin PHP ile birlikte kullanılabilmesi için OCI’nin 1.3 ve üstü sürümünün kurulması gerekmektedir. PHP ve OCI kurulumu için http://suhanerol.wordpress.com/2009/03/24/ubuntu-uzerinde-php-oci8-ve-oracle-instant-client-kurulumu/ makalesi incelenebilir.

.

CLIENT_RESULT_CACHE_SIZE veritabanı parametresi bu özelliğin aktif/devre dışı olduğunu belirleyen parametredir. 0 değeri bu özelliğin kapalı olmasını sağlar, 0 Haricinde bir değer atanması durumunda özellik aktif hale gelir. Atanan değer istemci tarafında sorgu sonuçlarının depolanması için hafızada ne kadar byte yer ayrılacağını belirler. Sorgu sonuçlarını istemcinin(webserver) RAM’inde tutulurlar.

.

$ sqlplus / as sysdba
SQL> alter system set client_result_cache_size=64M scope=spfile;
SQL> startup force
.

Bu komutlarla birlikte İstemci tarafında sorgu sonuçlarının tutulması özelliği aktif hale getirilmiş olmaktadır. İstemci RAM’inde 64MB’lık bir bölüm sorgu sonuçlarının depolanması için ayrılmış olmaktadır.

.

SQL>show parameter client_result_cache;

komutuyla bu parametreye ilişkin durumu listelenebilmektedir.

NAME                                           TYPE          VALUE
———————————— ———– ——————————
client_result_cache_lag               big integer       3000
client_result_cache_size              big integer       64M

.


Konu ile ilgili belirleyici bir diğer parametre de “RESULT_CACHE_MODE” dir. Bu parametre FORCE veya MANUAL olarak iki farklı değer alabilmektedir. MANUAL değeri varsayılan değerdir. Eğer bu değer MANUAL ise ve sorgu sonuçlarının istemcide tutulması isteniyorsa sorgulara /*+ result_cache */ hint’inin eklenmesi gerekmektedir. Aksi taktirde sorgu sonuçları tutulmayacaktır. Parametrenin FORCE olması durumunda uygun bütün sorguların sonuçları istemcide tutulacaktır. Eğer tutulması istenmeyen sorgular var ise bu sorgulara /*+ no_result_cache */ hint’inin eklenmesi gerekmektedir.

Görüldüğü gibi bu özelliğin kullanılması için PHP tarafında bir değişiklik yapılması gerekmemektedir. Oracle Server’da ilgili parametrelerin ve gerekiyorsa sorguların değiştirilmesi yeterli olmaktadır.

.

Aşağıdaki örnekte aynı sorgunun peş peşe çalıştırılması ve bunun Oracle Server’a ne şekilde yansıdığı gösterilmiştir.

.

<?php
$c=oci_connect(‘hr’,'hr’,'//oracleserver:1521/xxx’);
for($i=0;$i<100;$i++) {
$s=oci_parse($c,”select /*+ result_cache */ * from hr.employees”);
oci_execute($s,OCI_DEFAULT);
oci_fetch_all($s,$res);
}

?>

bu php betiği çalıştırıldıktan sonra oracle serverda bu sorgunun çalıştırılma istatistiği şu şekildedir.

.

SQL> select parse_calls, executions, sql_text from v$sql where sql_text like ‘%employees%’;

.

PARSE_CALLS        EXECUTIONS    SQL_TEXT
—————————————————————————————————–

2                                 2 ……………select / *+ result_cache */ * from hr.employees

.

Aynı PHP betiği tekrar çalıştırıldığında …

.

SQL> select parse_calls, executions, sql_text from v$sql where sql_text like ‘%employees%’;

.

PARSE_CALLS       EXECUTIONS           SQL_TEXT
—————————————————————————————————–
4                                   4 ………………select /*+ result_cache */ * from hr.employees

.

Bu duruma göre PHP betiğinde 100 kere çalıştırılan bir sorgu veritabanında 2 kere çalıştırılmıştır. Geriye kalan 98 sorgu istemcide çalıştırılmış ve oracle server çok daha az işlem yaptırılmıştır. Sorgu istemci tarafında geçerli olarak tutuluyor olsa bile ilk oci_execute() komutu veritabanında çalışıtırılır, daha sonraki çalıştırmalar istemci tarafındaki sorgu sonuçlarından bilgiyi alırlar. Bu php betiğinde sorgu ilk olarak veritabanında çalıştırılmıştır ve hr.employees tablosunda bir değişiklik olmadığından bundan soraki sorgular istemci tarafında çalışıtırılmış ve oracle serverdan yük alınmıştır. İkinci çalıştırılmanın sebebi şudur: CLIENT_RESULT_CACHE_LAG veritabanı parametresi istemci tarafındaki sorgu sonuçlarının geçerlilik süresini belirler ve bu süre varsayılan olarak 3000 milisaniyedir. PHP betiği çalıştıktan sonra 3ncü saniyede oci_execute() serverda çalıştırılır ve istemcideki sorgu sonuçlarının geçerliliği kontrol edilir.

.

Burada PHP geliştiricilerinin dikkat etmesi gereken bir konu vardır. oci_execute() fonksiyonun ikinci parametresi OCI_DEFAULT olarak belirtilmezse aşağıdaki tablo ortaya çıkacaktır.

.

SQL> select parse_calls, executions, sql_text from v$sql where sql_text like ‘%employees%’;

.

PARSE_CALLS        EXECUTIONS         SQL_TEXT
—————————————————————————————————–
2                                100 ……………select /*+ result_cache */ * from hr.employees

.

Görüldüğü gibi sorguların tamamı veritabanında çalıştırılmıştır. Bu yüzden OCI_DEFAULT parametresinin kullanılması gerekmektedir. OCI_DEFAULT değeri auto-commit özelliğini devreden çıkaran bir değerdir. Otomatik commit özelliğinin açık olması durumunda her oci_execute() fonksiyonu çağırımından sonra içsel olarak yapılan commit işleminin mevcut sorgu sonucunun değişimine sebep olabileceği ihtimali sebebiyle bir sonraki oci_execute() işlemi veritabanında çalışıtırılmaktadır.

.


Aşağıdaki örnekte aynı veriler üzerinde işlem yapan iki PHP betiğininden birinin güncelleme işlemi yapması sonucunda ortaya çıkan tablo gösterilmiştir. a.php betiği employees tablosundan peş peşe bilgi okurken b.php betiği a.php betiği çalışmaya başladıktan sonra aynı tablo üzerinde güncelleme işlemi yapmaktadır. Bu durumda a.php betiğindeki oci_execute() fonksiyonu b.php betiğinin güncelleme işlemini yapmasından sonra istemci sorgu sonuçlarının geçersiz olmasından dolayı oracle server tarafında çalışmaktadır. b.php betiği commit() fonksiyonun çalıştırdıktan sonra ise a.php tekrar istemci tarafındaki sorgu sonuçlarından yararlanmaya devam edecektir.

.

a.php

<?php
$c=oci_connect(‘hr’,'hr’,'//oracleserver:1521/xxx’);
for($i=0;$i<100;$i++) {
$s=oci_parse($c,”select /*+ result_cache */ * from hr.employees”);
oci_execute($s,OCI_DEFAULT);
oci_fetch_all($s,$res);
sleep(1);

}

?>

b.php

<?php
sleep(10); //10 sn bekle
$c=oci_pconnect(’system’,'123456′,’//oracleserver:1521/xxx’);
$s=oci_parse($c,”update hr.employees set salary=1000 where employee_id=100″);
oci_execute($s,OCI_DEFAULT);
sleep(10);
ocicommit($c);

?>

# php a.php &

#php b.php

.

komutları çalıştırıldığında b.php 10 sn bekleyecektir. bu süre içinde a.php sorgu sonuçlarını istemciden alacaktır. b.php ‘deki güncelleme işlemi çalıştığında ve tekrar 10 saniye beklemeye geçtiğinde a.php deki oci_execute() istemciden bilgi alamayacak ve sorguları veritabanında çalıştıracaktır. Çünkü b.php tabloda güncelleme yapmıştır ve henüz commit işlemini gerçekleştirmemiştir. OCI bu durumu algılar ve a.php devam eden sorgularında istemcideki sorgu sonuçlarını kullanmasını engeller, sorguların veritabanında çalıştırılması sağlar. b.php deki ocicommit() fonksiyonu çalıştırıldıktan sonra a.php deki sorgular güncellenen istemci sorgu sonuçları üzerinden çalışmaya devam eder.

.

İstemci Tarafında Depolanamayacak Sorgu Türleri

.

Bazı sorgu türleri bu özellik tarafından desteklenmemektedir. Sorguda /*+ result_cache */ hint’i kullanılsa bile bu sorgular depolanmayacaktırlar. Bu sorgulardan bazıları 11g ile gelen başka bir özellik olan “Sunucu Tarafında Sorgu Sonucu Depolama (RESULT CACHE)” özelliği sayesinde oracle server’da SGA da depolanabilirler.

  • View’lar

  • Uzak Nesneler (Remote Objects)

  • Flashback sorgular

  • PL/SQL fonksiyonu içeren sorgular

Bu özellikle ilgili istatistikler CLIENT_RESULT_CACHE_STATS$ görünümden takip edilebilir. OCI belirli aralıklar Oracle Server’a istatistik bilgileri göndermektedir.

.

Sonuç

.

OCI Result Cache özelliğinin hiç değişmeyen(Read-only) veya çok az değişen tablolar için kullanılmasının daha doğru bir karar olduğu görülmektedir. Çok sık çağırılan fakat nispeten daha fazla değişikliğe uğrayan sorgularda da bu özelliğin kullanılması uygun olabilir. İstemci tarafındaki RAM maliyetinin Oracle Server tarafında olduğundan daha düşük olması bu özelliğin daha yaygın kullanılmasının da bir sebebi olabilir.

.

OCI Result Cache özelliği, Oracle’ın ölçeklenebilirlik ve performans konularında bir adım daha atmasına sağlamaktadır. Yazılım geliştiricilerin dosya sisteminde sorgu sonuçlarını tutmak ve bunları kullanarak uygulamaya çalıştıkları Caching uyarlama çalışmalarının mevcut bütün handikaplarını ortadan kaldıran ve tek bir satır kod yazmadan kullanıma sunan bu özellik , Server Taraflı Sorgu Sonucu Depolama (RESULT CACHE) ve DRCP özellikleriyle de birleştirildiğinde, PHP gibi betik lisanlarının diğer üst düzey lisanlar karşısındaki handikaplarının büyük bir kısmının ortadan kalkmasını da sağlamaktadır. Oracle tarafından desteklenen PHP , 11g ve OCI’daki yenilikler sayesinde Oracle Veritabanı kullanacak yazılımlar için güçlü bir alternatif haline gelmiştir.

Henüz Yorum Yok »

Henüz yorum yapılmamış.

Bu yazıya yapılan yorumlar için RSS beslemeleri. URI'nin geri izlemesini yap.

Yorum yapın

WordPress.com'dan blog alın.