DĐNAMĐK ve STATĐK SQL KULLANMANIN PERFORMANSA ETKĐSĐ

Benzer belgeler
ORACLE DA KÜRSÖRLER. Gerekli sistem değişkenleri

PostgreSQL ve PL/pgSQL

Bellek Yönetimiyle İlgili Notlar ORACLE BELLEK YÖNETĐMĐYLE ĐLGĐLĐ NOTLAR

PostgreSQL ve PL/pgSQL

ORACLE INDEX SIKIŞTIRMA TEKNĐKLERĐ

Kullanıcı tanımlı fonksiyonlar SQL2000 ile gelen özelliklerden biridir. Fonksiyonlar tek bir değer veya tablo döndürmek için kullanılır.

Sorgudan elde edilen değerin değişkenlere aktarılmasını sağlar. Sorgudan tek satır dönmesi gerekir. Çok satır dönerse hata verir.

SAKLI YORDAM (Stored Procedure) Sibel Somyürek

UTL_FILE PERFORMANSI

Sorgudan elde edilen değerin değişkenlere aktarılmasını sağlar. Sorgudan tek satır dönmesi gerekir, aksi durumda hata olur.

Exadata Üzerinde Veri Sıkıştırma Yöntemleri

VERİ TABANI YÖNETİM SİSTEMLERİ II. 5. SQL PROGRAMLAMADA CURSOR (İMLEÇ) ve TRIGGERS (TETİKLEMELER)

Fonksiyonlar istenilen deger tipinde dönüs yapabilir. INT, VARCHAR deger döndürebileceğiniz gibi bir tablo da döndürebilirsiniz.

KULLANICI TANIMLI FONKSİYONLAR (Devam)

KULLANICI TANIMLI FONKSİYONLAR (Devam)

Oracle da kullanılan veri tipleri:

SQL TRIGGERS (Tetikleyiciler)

VIEW LERDE SQL HINT KULLANIMI

KULLANICI TANIMLI FONKSİYONLAR

PCTFREE - PCTUSED ORACLE DEĞERLERĐ

Cursor. Bir veri tipi olarak da ele alınabilen Transact-SQL Sunucu Cursor şu aşamalardan geçirilerek kullanılır.

TESİ. indeks. söylenebilir?? bir ilişkidir d) Hiçbiri. veya somutlaştırılmış. düzeyidir? sağlayabilir? sına. d) Hepsi. olabilir? c) Verilerin d) Hepsi

8 Oracle da tablo yapısı içinde otomatik artan kolon yoktur. (identity kolon

STORED PROCEDURE LER (Saklı Yordamlar)

T-SQL NEDİR? Microsoft T-SQL Transact-SQL

Emrah UYSAL 1 TABLESPACE ENCRYPTION ORACLE 11G

EXISTS VE NOT EXISTS fonksiyonları

SQL PROGRAMLAMA. Bir batch, bir arada bulunan bir dizi SQL deyimidir. Batch ayıracı GO deyimidir.

Unutulmuş Özellikler: Oracle Veritabanına Yaptığınız Yatırımı Sonuna Kadar Kullanın

2- Total de 8000 byte yer tutup 4000 karakter olarak kullanabildiğimiz tip aşağıdakilerden hangisidir?

ORACLE VERĐTABANINDA TABLO ve INDEX SIKIŞTIRMA

DAO İLE SQL KOMUTLARI. Sql komutlarını artık veri tabanında kullanmaktan başka çaremiz yok arkadaşlar. Şimdi bu sql derslerimize başlayalım.

SQL Stored Procedure

BLG4134 Görsel Programlama III. Öğr. Grv. Aybike ŞİMŞEK

«BM364» Veritabanı Uygulamaları

VERİ TABANI YÖNETİM SİSTEMLERİ II. 3. SQL PROGRAMLAMA BLOKLARI ve AKIŞ DENETİMİ

VERİ TABANI ve YÖNETİMİ

Öğr. Gör. Cansu AYVAZ GÜVEN VERİTABANI-II. Değişken Tanımlama Ve Akış Kontrol Deyimleri

YAPISAL SORGULAMA DİLİ (SQL)

-- işareti tek satırlık açıklamalarda kullanılır. Açıklama olarak yazılan satırın önüne konulması yeterlidir.

PostgreSQL Veritabanı Sunucusu. 8.2 neler getiriyor?

Üst Düzey Programlama

Bir çeşit prosedür. Ancak bu prosedür kendiliğinden çalışır. Çalışması için tabloya veri eklemek, veri silmek, veri değiştirmek yeterlidir.

Veritabanı Tasarımı. Kullanıcı Erişimini Kontrol Etme

SQL Komutları (2) Uzm. Murat YAZICI

Microsoft SQL Server Sorgulama

C#.Net & Linq (Language Integrated Query)

BÖLÜM- 8: DİĞER ŞEMA NESNELERİNİ OLUŞTURMA

Aşağıdaki tabloyu inceleyin. Yeni kayıt girme, var olan bir kaydı silme veya güncelleme işlemlerini bu tabloya göre yapacağız.

Veri Tabanı SQL Server ve Management Studio kurulum linkleri:

Öğr. Gör. Cansu AYVAZ GÜVEN VERİTABANI-II. Değişken Tanımlama Ve Akış Kontrol Deyimleri

PHP+Memory Cache+PostgreSQL Kullanarak Performanslı Veritabanı Uygulaması Geliştirme

VERİ TABANI YÖNETİM SİSTEMLERİ II. 4. SQL PROGRAMLAMADA PROCEDURE ve FUNCTION

Yukarıdakilerden hangileri DML (Data Manipulation Language) ile gerçekleştirilir?

Data Programming SQL Language. Elbistan Meslek Yüksek Okulu Bahar Yarıyılı

Genel Kavramlar. Bilgisayar ortamında işlenebilecek durumda bulunan kayıtlar. Birbiri ile ilişkili veriler topluluğu ve veriler arası ilişkiler

20461C Querying Microsoft SQL Server Modül Seviye Belirleme Testi

Advanced Oracle SQL Tuning

BÖLÜM- 9: KULLANICI ERİŞİMLERİNİ YÖNETMEK

Bu işleçlerin dışında, aşağıda belirtilen karşılaştırma işleçlerinden de yararlanılır.

ACCESS PLATFORMUNDA SQL

Çok tablolu sorgulamalar

Veri Tabanı Programlamaya Giriş

Örnek: HAFTA12B isimli bir kullanıcı tanımlayalım. Bu kullanıcıya gerekli yetkileri verelim.

1. PL/SQL de kontrol yapıları

TRIGGER. Trigger lar, tablo üzerinde tanımlanabilen ve bu tablo üzerinde bir işlem gerçekleştiğinde tetiklenen programlama ögeleridir.

VERİ TABANI YÖNETİM SİSTEMLERİ II. 9. FORMLAR ve ORACLE FORMS PROGRAMINDA FORM OLUŞTURMA

BÖLÜM- 11: BÜYÜK VERİ KÜMELERİ

Masa üstünde vt34.mdb dosyası var, onu projemize eklemek için, App_Data ya sağ tıkla Add Existing Item vt34.mdb adlı dosyayı seç Add

Mysql Veritabanı Komutları

Veritabanında Saklı Yordamlar: Bir Veritabanı Tasarımı ve Web Uygulaması

ASP.NET CLASS KULLANARAK VERİTABANI İŞLEMLERİ

NOT: VERİTABANINDAKİ TABLOLARI OLUŞTURMAYI DA UNUTMAYACAĞIZ.

HB1002: ORACLE 10G VERĐTABANI PL/SQL ile PROGRAMLAMA (32 saat)

Veritabanı Yönetim Sistemleri (Başarım Eniyileme Performance Tuning)

1. Araçların tüm bilgilerini ve bağlı oldukları kiralama noktasının adres ve telefonunu içeren tam listesi:

Liquibase ile Veri Tabanı Değişiklik Yönetimi

SP_RENAMEDB eski_isim, yeni_isim VEYA SP_RENAMEDB 'eski isim', 'yeni isim'

Veritabanı sistemlerinde veri bütünlüğünü sağlayabilmek için CONSTRAINTS olarak adlandırılan bazı zorlayıcı ifadeler kullanılabilir.

Aşağıdaki şemaya dikkat edin. Sorgulamalarımızı genellikle bu şemaya göre yapacağız.

Aşağıdaki tabloyu inceleyin. Sorgulama işlemlerini bu tabloya göre yapacağız.

VERİ TABANI YÖNETİM SİSTEMLERİ I

Bu uygulamayı yapabilmek için SQL Server'da Query Analyzer kullanabilmekle beraber, ADO.NET bilgisine sahip olmanız gerekir.

Veritabanı Yönetim Sistemleri (Veritabanı Tasarımı) SQL (Structured Query Language)

SQL'e Giriş. SELECT Deyimi. SQL Komutları. Yardımcı Deyimler

NESNEYE YÖNELİK PROGRAMLAMA

Sayfa 1 / 8. Tabo yapıları

MOBİL UYGULAMA GELİŞTİRME

PHP Günleri 2013#1. mysql_* Fonksiyonları Ömrünü Doldurmak Üzere. Peki Şimdi Ne Olacak? Özgür Yazılım A.Ş.

ASM (Automatic Storage Manager) 11 Mayıs 2009

SQL veri tabalarına erişmek ve onları kullanmak için geliştirilmiş bir lisandır.

BÖLÜM -6: VERİLERİ DEĞİŞTİRMEK

Veritabanına Uygulanması

5 SQL- Yapısal Sorgulama Dili. Veritabanı 1

SQL e Giriş. Uzm. Murat YAZICI

MT487_2005guz_final_cevaplar (cevaplar vurgulu ve koyu yazılmıştır)

SQL Deyimleri. Öğr.Gör.Volkan ALTINTAŞ Volkanaltintas.com

EROL AKGÜL

VERİ TABANI YÖNETİM SİSTEMLERİ I

Veritabanı Tasarımı. Seriler ile Çalışma

Transkript:

DĐNAMĐK ve STATĐK SQL KULLANMANIN PERFORMANSA ETKĐSĐ 1

İçindekiler 1. SQL Yazımında Dikkat Edilecekler... 3 2. TAMAMEN DİNAMİK SQL ÖRNEĞİ... 4 3. DİNAMİK SQL İÇİN CURSOR_SHARING I FORCE ETMEK... 5 4. DİNAMİK PL/SQL BLOĞUNDA BIND DEĞİŞKENLE ÇALIŞMAK... 6 5. TAMAMEN STATİK ÇALIŞMAK... 8 6. STATİK VEYA DİNAMİK KOD YAZIMINA KARAR VERMEK... 9 2

1. SQL Yazımında Dikkat Edilecekler SQL ifadelerini çeşitli nedenlerle dinamik yazmamız gerekebilir. Ancak dinamik yazılacak SQL ifadelerinin işlenmesi (parse) ve buna göre bir çalışma planı (execution plan) hazırlanması önemli maliyettir. Örneğin dinamik bir ifade ile statik yazılan bir ifadenin performans farkı aşağıda net olarak görülebilir: -- TABLO YARATIYORUZ CREATE TABLE D_CCEBI.DENEME ( ID NUMBER ); -- HARD PARSE set timing on DECLARE i PLS_INTEGER; FOR i IN 1..500000 EXECUTE IMMEDIATE 'INSERT INTO D_CCEBI.DENEME VALUES( ' i ')'; COMMIT; Elapsed: 00:06:27.51 Şimdi de bu işlemi statik olacak şekilde değiştirelim. -- TABLOYU SĐLĐYORUZ truncate table d_ccebi.deneme; -- PROSEDÜR YARATALIM CREATE OR REPLACE PROCEDURE D_CCEBI.DENEME_INSERT ( ID NUMBER ) AS INSERT INTO d_ccebi.deneme values( id ); -- PROSEDÜR ÜZERĐNDEN KAYIT GĐRĐYORUZ set timing on DECLARE i PLS_INTEGER; FOR i IN 1..500000 D_CCEBI.DENEME_INSERT( i ); COMMIT; Elapsed: 00:00:32.07 Görüldüğü gibi tekrar tekrar ifadenin işlenmesine engel olursak çok ciddi bir performans artışı sağlayabiliyoruz. Söz konusu OLTP bir ortamsa, bind değişken kullanımı yukarıdaki örnekte de görüldüğü gibi çok yararlı olabilir. Ancak her zaman 3

statik yazmak ya da bind değişken kullanmak çok güzel sonuçlar vermeyecektir. Bazı durumlar da dinamik sql ifadelerine ihtiyaç duyuyoruz. Örneğin bir datawarehouse uygulamasında, saatlerce süren sorgular düşünüldüğünde verilen değerlere göre execution plan ın tekrar tekrar hesaplanması çok daha verimli olabilir. Java vb. modern programlama dillerinde SQL ifadelerini program içinden dinamik şekilde yazabilirsiniz. Bunu PL/SQL ile yapmak da mümkün. Bu yazıda dinamik ve statik sql örnekleriyle, execution plan arasındaki bağı açıklamaya çalışacağım. 2. TAMAMEN DİNAMİK SQL ÖRNEĞİ Basit bir test yapıp, DBA_OBJECTS tablosundan nesne numarasına göre bazı bilgileri sorgulayan ifadeleri oluşturacağız. Ancak bunu yapmadan önce sonuçları daha iyi analiz etmek için shared pool u flush etmemiz yararlı olur: -- SHARED POOL FLUSH EDILIR SQL> ALTER SYSTEM FLUSH SHARED_POOL; -- IFADEYI OLUSTURUYORUZ CREATE OR REPLACE PROCEDURE query_obj( obj_id varchar ) IS TYPE cv_type IS REF CURSOR; cv cv_type; obj_name varchar2(30); query_str varchar2(1000); val varchar2(32000); ob_id number; query_str := 'SELECT OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE object_id =' OBJ_ID; OPEN cv FOR query_str; FETCH cv INTO val, ob_id; EXIT WHEN cv%notfound; CLOSE cv; FOR i in 1..10000 Elapsed: 00:01:00.75 4

Oluşturulan SQL ifadelerini ve bunlara ait execution plan ları görmek için aşağıdaki sorguları kullanıyoruz: select count(*) from v$sqlarea where sql_text like 'SELECT OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE%' select count(*) from v$sql_plan where sql_id in ( select sql_id from v$sqlarea where sql_text like ' SELECT OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE%' )and id = 0; Çalıştırdığımız ifade sonucunda 10bin adet ayrı execution plan oluşuyor ve işlemin yavaş olduğunu görüyoruz. Ancak dikkat etmemiz gereken bir durum daha var: 4000.adımdan sonra eski planlar hızla eziliyor. (Kullandığınız bellek boyutuna ve ortamın yoğunluğuna göre hiç ezilmemesi de mümkün...) 3. DİNAMİK SQL İÇİN CURSOR_SHARING I FORCE ETMEK Bind değişken kullanmanın çok iyi sonuçlar yaratacağı bazı durumlarda kodun içine müdahele şansımız olmayabilir. Bu gibi durumlarda cursor_sharing parametresi kullanarak aynı SQL ifadelerinin bind değişken kullanmasını 'zorlayabiliriz'. Normalde cursor_sharing exact değeriyle gelir; ancak bunu force ederek, aynı yazılmış SQL lerde bind değişken atamış gibi davranmamız mümkündür. Şimdi aynı örneği cursor_sharing parametresini session bazında force ederek tekrar ediyoruz. (Doğru analiz için her test öncesinde flush işlemini mutlaka yapmamız gerektiğini unutmamak gerekiyor.) CREATE OR REPLACE PROCEDURE query_obj( obj_id varchar) IS TYPE cv_type IS REF CURSOR; cv cv_type; obj_name varchar2(30); query_str varchar2(1000); val varchar2(32000); ob_id number; query_str := 'SELECT OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE object_id =' OBJ_ID; OPEN cv FOR query_str; FETCH cv INTO val, ob_id; EXIT WHEN cv%notfound; CLOSE cv; 5

-- SESSION BAZINDA CURSOR_SHARING YAPIYORUZ ALTER SESSION SET CURSOR_SHARING = FORCE; FOR i in 1..10000 Session altered. Elapsed: 00:00:02.32 Sadece tek bir execution plan oluştu, bu yüzden bariz bir hızlanma var. SELECT OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE object_id =:"SYS_B_0" 4. DİNAMİK PL/SQL BLOĞUNDA BIND DEĞİŞKENLE ÇALIŞMAK Dinamik SQL ifadeleri içinde bind değişken kullanmak mümkündür. CREATE OR REPLACE PROCEDURE query_obj( obj_id varchar ) IS TYPE cv_type IS REF CURSOR; cv cv_type; obj_name varchar2(30); query_str varchar2(1000); val varchar2(32000); ob_id number; query_str := 'SELECT OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE object_id = :OBJ_ID'; OPEN cv FOR query_str USING obj_id; FETCH cv INTO val, ob_id; EXIT WHEN cv%notfound; CLOSE cv; FOR i in 1..10000 Elapsed: 00:00:02.15 6

Yukarıdaki PL/SQL bloğu bind değişken kullanan dinamik bir sql örneğidir. Đfade dinamik olduğu hâlde bind değişken sayesinde tek bir execution plan oluşur ve performans çok ciddi oranda artar. SELECT OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE object_id = :OBJ_ID Elbette burada önemli bir soru aklımıza takılabilir: Madem bind değişken kullanıyoruz, neden ifadeyi statik yazmıyoruz? Yukarıdaki ifade çok basit bir örnek, ne gelirse gelsin, her zaman aynı ifadeyi çalıştırıyor. Hâlbuki gelen ifadeye göre SQL hint veriyor olsaydık, durum daha net anlaşılırdı. Örneğin gönderilen değer 0 ile 1000 arasında gelirse INDEX hint i verebileceğimiz, 1000 den büyükse FULL gitmesini isteyeceğimiz bir şey yapmayı deneyebiliriz: CREATE OR REPLACE PROCEDURE query_obj( obj_id varchar ) IS TYPE cv_type IS REF CURSOR; cv cv_type; obj_name varchar2(30); query_str varchar2(1000); val varchar2(32000); ob_id number; hint_statement varchar2(200); IF obj_id >= 0 AND obj_id <= 1000 THEN hint_statement:='/*+index( DBA_OBJECTS )*/'; ELSE hint_statement:='/*+full( DBA_OBJECTS )*/'; END IF; query_str := 'SELECT ' hint_statement ' OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE object_id = :OBJ_ID'; OPEN cv FOR query_str USING obj_id; FETCH cv INTO val, ob_id; EXIT WHEN cv%notfound; CLOSE cv; FOR i in 1..10000 Elapsed: 00:00:02.81 7

Yaratılan planları kontrol ettiğimizde iki tane SQL ifadesi yakalıyoruz: SELECT /*+INDEX( DBA_OBJECTS )*/ OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE object_id = :OBJ_ID SELECT /*+FULL( DBA_OBJECTS )*/ OBJECT_NAME, OBJECT_ID FROM DBA_OBJECTS WHERE object_id = :OBJ_ID Verdiğimiz örnekler DBA_OBJECTS view i ile ilgili olduğundan cost ile ilgili sonuçlar farklı olmuyor. Ancak verilecek hint e göre çok farklı execution plan lar oluşturmak mümkün. Ve gönderilen değere göre seçicilik (selectivity) değişeceğinden, bunun avantaj sağlayacağı birçok durum yaratılabilir. 5. TAMAMEN STATİK ÇALIŞMAK OLTP olmak üzere tasarlanan veritabanlarında en çok kullanacağımız/kullandığımız durumdur. CREATE OR REPLACE PROCEDURE query_obj( v_object_id varchar ) IS obj_name varchar2(30); obj_id number; CURSOR C IS SELECT object_name,object_id FROM DBA_OBJECTS WHERE object_id=v_object_id; OPEN c; FETCH c INTO obj_name, obj_id; EXIT WHEN c%notfound; CLOSE c; / FOR i in 1..10000 Elapsed: 00:00:01.21 Oluşan tek execution plan aşağıdaki içindir: SELECT OBJECT_NAME,OBJECT_ID FROM DBA_OBJECTS WHERE OBJECT_ID= :B1 Bütün uygulamalar arasında en hızlı çalışan tamamen statik yazılmış kod oldu. 8

6. STATİK VEYA DİNAMİK KOD YAZIMINA KARAR VERMEK Denemelerden de görüldüğü gibi BIND değişkenlerle çalışmak çok daha hızlı sonuç elde etmemizi sağlar; çünkü execution plan tekrar hesaplanmaz. Dinamik yazılmış sql ifadelerine gelirsek, bunlar için de bind değişken kullanmamız mümkündür. Ya da yazılımcı bunu yapmazsa, session bazında cursor_sharing i force edip, bind değişken kullanımını zorlayabiliriz. Yine çok daha performanslı çalıştığı görülebilir. Statik ya da dinamik kod yazarken çok önemli bir ayrıma gitmemiz gerekiyor: Bind değişken kullanmak her zaman güzel sonuçlar vermeyecektir. Özellikle büyük raporların döndüğü bir sorgu ise bind değişkenin yarardan çok zararı olabilir. Örneğin bind değişken kullanan bir sorguda, sisteme bağlanan ilk kullanıcı 1 yıllık bir sorgu çalıştırdı ve ilgili tabloya full gitti diye düşünelim. Bu durumda bundan sonra siz tek gün dahi çalıştırsanız, tabloya full gitmeye devam edersiniz. Hâlbuki dinamik yazılan SQL ifadesi olsa, her seferinde plan tekrar gözden geçirileceğinden çalışma planı daha doğru olacaktır. Statik ya da dinamik kod yazma ayrımı yaparken, çalıştırılacak ifadenin ne kadar veri çekeceği, kimler tarafından kullanılacağı, data dağılımının homojenliği vb. birçok faktör göz önüne alınmalıdır. Ayda bir kere çalışan, çok büyük raporlar için statik sql ifadeleri yarardan çok zarar getirebilir, çünkü ilk çalıştırılan değerlere göre execution plan hesaplanır. Ama her dakika çalıştırılan ifadeler için de dinamik bir kod yazmak tehlikelidir; diğer planların bellekteki çabuk atılmasına yol açar ve parse CPU gücü gerektirir. Ne yazık ki nerede ne yazılacağını belirleyebileceğimiz altın bir kural yok. Duruma göre gözlem yapıp, en uygun ifadeyi belirlemek ve testlerle kontrol etmek gerekiyor. 9