Execution Öncesinde ve Sonrasında “Execution Plan”

Herkese Selam,

Bu yazıda sizlere EXECUTION PLAN‘nı sorguyu çalışmadan önce ve sorguyu çalıştıktan sonra inceleyip, sık düşülen bir yanılgıyı ortaya koymaya çalışacağım. Umarım farkındalık anlamında faydalı bir yazı olur.

Hakim olunan yanılgılardan biri, bir sorguyu çalıştırmadan önce o sorgu için aldığımız EXECUTION PLANIN, sorgunun çalışma zamanında(run time) aynı plan ile çalışacağına inanmamızdır. Çoğu zaman sorguyu çalıştırmadan önce çıkan execution plana bakarak, o sorgunun yanlış planda çalışıp, çalışmayacağı hakkında yorumlar yapıp sorguyu henüz hiç çalıştırmadan müdahale (HINT vb yollar ile) edebiliyoruz. Bu durumda belkide run time’da doğru planda çalışacak bir sorgunun, doğru planda çalışmasına engel olarak uygulama veya servislerimizin yanlış planda belkide performanssız çalışmasına sebep oluyoruz.

Genellikle bu tarz müdehaleleri test veya developement ortamlarında yapmak, production ortamlarında kötü sonuçlar elde etmemiz anlamına gelebilir. Test ve developement ortamları çoğunluk la hem data hemde metadata anlamında production ortamları ile aynı olmadığı için bu ortamlarda alınan planlara güvenip olası bir tuning çalışmasına girmek işin başlangıcında hatalar yapmamıza sebebiyet verebilir.

Peki bu durumu önlemek için ne yapabiliriz? Bu tarz durumları önlemek için uygulanabilecek en iyi çözüm,  execution öncesinde alınan plan hakkında yorum veya aksiyon almadan önce en az 1 kez, olabiliyorsa bir kaç kez sorguyu çalıştırıp run time’da nasıl bir plan ile çalışıp çalışmadığını kontrol edip buna göre aksiyon almaktır.

Unutulmamalıdır ki; Oracle Cost base optimizer arka planda milisaniyeler mertebesinde belli parametrelere bakarak sorgu planları üretmekte ve yaptığı hesaba göre en uygun olanı ile de sorguyu çalıştırmakta. Bu bağlamda bir sorgu için doğru planın üretilmesini sağlayabilmek için öncelikle gerekli işlemleri veritabanı üzerinde yapmak gerekir. Bu işlemler tablo istatistiklerini güncel tutmak, tabloları gerektiği yerlerde partition veya index gibi yapılar ile destekleyerek veriye erişim performansını arttırmak hemen ilk akla gelenler.

Oracle Cost Base optimizer bazen ortamda çalışan sorguların planlarını da değiştirebilmekte. Buna neden olan şeyler;
• İstatistiklerin büyük ölçüde değişmesi.
• Optimizer ile ilgili database parametrelerinde değişiklik yapılması
• Yazılan sorgunun değişikliğe uğraması

Burada olası en büyük seçenek istatistiklerin değişmesi. Cost based optimzer istatistikleri yoğun bir şekilde kullandığı için olası major değişiklikte sorgu planının bundan etkileneceği unutulmamalıdır. Bu bağlamda plan stabilizasyonu bağlamında tablo istatistiklerinin etkisi oldukça fazla olduğu söylenebilir.

Bind variable kullanmanın sistem performansını pozitif yönde etkilediği yadsınamaz bir gerçek. Ancak bind variable ların bind peeking adında negatif bir etkisi de bulunmakta. Bu konu düşünüldüğünde bind variable kullanılarak yazılan SQL’lerde sorgular bazı parametreler için istenildiği gibi çalışmayabilir. Yine bu durumu anlayabilmek için sorgu öncesinde ve run time’daki planlar karşılaştırılarak gerekli aksiyon alınabilir.

Şimdi soruguyu çalıştırmadan önce ve çalıştırdıktan sonra sorguların planlarının nasıl alınabileceğine bakalım. Akabinde bind variable içeren sorguları nasıl monitör edebilirizi inceleyelim.

-- Execution oncesi (sqlplus üzerinden asagidaki gibi alinabilir)
EXPLAIN PLAN
   FOR
      SELECT * FROM hr.employees;

SELECT * FROM TABLE (DBMS_XPLAN.display);

explain plan

veya kullandığımız editörler üzerinden’de herhangi bir sorgu yazmadan kısayollar vasıtası ile planı görebiliriz.

Toad için : Sorgu seçildikten sonra Ctrl+E kombinasyonuna basılarak execution plan görülebilir. Çıktı aşağıdaki formatta olur.

toadexplainplan

PLSQL Developer için: Sorgu seçilip F5 tuşuna basılarak execution plan görüntülenebilir.

Oracle SQL Developer için: Sorgu seçilip F10 tuşuna basılarak execution plan görüntülenebilir.

Peki sorgu çalıştıktan sonra sorgunun çalıştığı planı nasıl görebilirim? Burada kullanılabilecek bir çok yöntem söylenebilir ancak benim en sık kullandığım yöntem sorgu içine bir comment ekleyerek sorgunun sql_id sini bulmayı kolaylaştırıp sorgunun çalıştığı planı görüntülemek oluyor.

-- Sorguyu ilk etapta çalıştırıyoruz.
SELECT  /* emrahmete */ *                                                       
        FROM hr.employees;
-- Çalıştırma işlemi bittikten sonra  sorgunun sql_id sini buluyorum
SELECT *
  FROM v$sql
 WHERE sql_text LIKE '%emrahmete%';   

sqlv$

-- Şimdi bulduğumuz id ile planı görünteleyelim.
SET linesize 2000
SELECT * FROM TABLE (DBMS_XPLAN.display_cursor('b80a109vxwkkf'));

afterplan

Evet sorgunun öncesinde ve sonrasında nasıl bir plan ile çalıştığını görüntüledik. Şimdi birde bind variable kullandığımız sorguların nasıl bir planda execute edildiğine bakalım.

-- bind variable tanımlayıp sorguya verdim ve sorguyu calistirdim
VARIABLE bind NUMBER;
EXEC :bind := 100;

SELECT * /*binding*/
  FROM hr.employees e
 WHERE E.EMPLOYEE_ID > :bind;

-- calisan sorgumun sql_id sini alıyorum 
SELECT *
  FROM v$sql
 WHERE sql_text LIKE '%binding%';

-- sorgumun planına bakıyorum
SET linesize 2000
SELECT * FROM TABLE (DBMS_XPLAN.display_cursor('c8w9zmdbpxa6p'));

planbind

 

Evet sorgumun planından hangi değerle execute edildiğini göremiyorum bu yüzden o değerleri görüntülemek için aşağıdaki sorguyu yazıyorum.

SELECT hash_value,
       sql_id,
       name,
       datatype_string,
       last_captured,
       value_string
  FROM v$sql_bind_capture
 WHERE sql_id = 'c8w9zmdbpxa6p';

binding

Evet bu yazıda normal durumda ve binding durumunda planları nasıl görüntüleyeceğimizi ve yorumlamak için nelere dikkat edeceğimize değindik umarım farkındalık anlamında faydalı bir yazı olmuştur.

Advertisements

About ... from Emrah METE

Bilgisayar Mühendisi
This entry was posted in Uncategorized and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s