Özet: Doğru ve performanslı sorgu(SQL) yazmanın ipuçları ve dikkat edilmesi gereken noktalar anlatılıyor. Serinin 2. yazısı.

SQL Performanslarında Dikkat Edilmesi Gerekenler -1  ile başladığımız serinin devamı niteliğinde aşağıdaki durumları Oracle Sql performansı noktasında dikkatinize sunuyoruz;

4- Sorgularımızda boyutu çok büyük tabloları kullanıyorsak mümkün olduğunca ORDER BY veya ORDER BY … DESC sıralama fonksiyonlarından kaçınmalı yada çok az kullanmalıyız. Bu sıralama fonksyonlarıyla sorgu sonucumuzun daha geç geleceğini unutmayın. 204 GB boyutundaki aşağıdaki “.._log” tablosunda order by kullandığımızda hem temp tablespace alanını şişirmiş oluyoruz hem de sorgunun maliyetini (cost) artırmış oluyoruz.

4_1

4_2

5- Sorgularımızda boyutu büyük tablolara erişirken PARALLEL hinti kullanarak birkaç process ile daha kısa sürede sonuç alabiliriz. Bu parallel process sayımız 4,8,16,32,64 veya 128 olabilir. Bunda veritabanımızın ve tablomuz üzerindeki parallellik parametreleri belirleyicidir. Parallelik hinti verdiğimizde özellikle veritabanı CPU kaynağını yoğun kullanacağından dolayı OLTP (Online Transaction Processing) veritabanlarında genellikle kullanılması sakıncalıdır. Çünkü diğer sessionların ihtiyacı olan sistem kaynaklarını kullanamamasına, Uygulama ekranlarınının yavaş tepki vermesine ve yeni kullanıcı bağlantılarının sağlanamamasına neden olabilir. Bazen gerekirse çok nadir olarak birkaç sorguda kullanılabilir. Daha çok veriambarı (DWH) veritabanlarındaki sorgularımızda PARALLEL hintini kullanırız. Sorguda PARALLEL hinti uygulamadan önce mutlaka dba’lere danışılması gerekmektedir.

select /* PARALLEL(a ,16) */ from table_name a ...

Veritabanlarından birinde yaşadığımız örneklerden biri;

Aşağıdaki ekranlardan da görebileceğiniz üzere sorguda çok fazla parallelikler verilerek 180 kadar aktif session aynı anda çalışmış oldu ve veritabanı yeni session alamamaya cevap verememeye başladı (Failed to connect to database instance: ORA-12537: TNS:connection closed (DBD ERROR: OCIServerAttach).) Sorgu kill edildikten sonra veritabanı kendini toparlamış oldu.

5_1

5_2

5_3

6- Bazen sorguda kullandığınız Optimizer HINT (USE_NL, LEADING, INDEX, NO_INDEX, ALL_ROWS, FIRST_ROWS, FULL, vb.) aylar sonra etkisiz olabilir veya da performansı olumsuz etkileyebilir. Bunun sebepleri olarak; sorgunun yapısının değiştirilmesi, kullanılan tablolara yeni kolonların eklenmesi, yeni indexlerin eklenmesi, mevcut indexlerin drop edilmesi, vs. olabilir. Dolayısıyla sorguda kullanılan tablolar ve indexleri üzerinde bu tarz yapısal değişiklikler sözkonusu olduğunda özellikle HINT durumları tekrar gözden geçirilmelidir. HINT’li ve HINT’siz kullanımı ile sorgu performansı karşılaştırılmalıdır. Sorguda Optimizer HINT uygulamadan önce mutlaka dba’lere danışılması gerekmektedir.

select /*+ NO_INDEX(a IDX_DENEME_01) */  from table_name a ...

Daha önce aşağıdaki hint uygulanarak performans sağlayan sorguda kullanılan tabloların kolonlarında yapılan değişiklikler ve yeni index lerin eklenmesiyle bu hint artık etkisini yitirmiş performansı olumsuz etkilemeye başlamıştır. Hint kaldırıldığında maliyeti oldukça düşmüştür.

6_1

6_2

7- Sorguda kullanılan objelerin (tablo, index) istatistiklerinin güncel olup olmadığı kontrol edilmeli, değilse güncellenmelidir. Objelerin istatistikleri güncel değilse optimizer sağlıklı bir execution plan sunamayacaktır, eski istatistiki bilgilere göre cost hesaplayacaktır.

SELECT owner, table_name, last_analyzed  FROM dba_tables WHERE owner = 'ORHAN' AND table_name = 'TABLE_1'

OWNER                          TABLE_NAME                     LAST_ANALYZED

------------------------------ ------------------------------ -------------

ORHAN                          TABLE_1                        20/02/2017  

1 row selected.

Tablo ve indexlerinin istatistiğinin geçilmeden önceki ve sonraki cost hesabını karşılaştırabilirsiniz:

7_1

7_2

7_3

7_4

 

Serinin 3. yazısında görüşmek üzere, performanslı sorgular dileriz  🙂