Daha önceki yazılarımda Oracle ve SQL ile ilgili temel bilgileri vermeye çalıştım.Şimdi ise tüm Oracle developerların çok dikkat etmeleri gereken bir konu; tuning’den bahsedeceğim. Üzerinde çalıştığımız dataların boyutları büyüdükçe, database’i etkili ve verimli kullanmak daha önemli bir hale gelmekte. Yapılması gereken işi aynen yapacak sadece yapış metodunda ufak değişiklikler yaparak büyük verimlilik kazanacagız.
SQL OPTIMIZER NEDİR ?
Herhangi bir SQL sorgusu çalıştırıldığında, istenilen bilgiye nasıl ulaşılacağına “Optimizer” adı verilen
veri tabanı optimizasyon birleşeni karar vermektedir. Oracle, kullanıcılarına tahminler üzerine çalışan
“Rule-Based Optimizer” ve daha çok akıl yürütme yöntemi ile çalışan “Cost-Based Optimizer” olmak
üzere iki adet optimizasyon seçeneği sunmaktadır.
Rule-Based Optimizer
Veri tabanına ulaşılırken, Rule-Based Optimizer (RBO) ile önceden tanımlanmış kurallar seti
kullanılarak hangi yolun izleneceğine karar verilir. Burada bahsedilen kurallar “SELECT /*+ RULE
*/. . .” şeklinde kullanılmaktadır ve böylece veri tabanında hangi indeksin kullanılacağı gibi ek
bilgiler verilmektedir. Eğer bu yöntem kullanılacaksa, RDBMS‘de aşağıdaki tanımlamaların yapılması
gerekmektedir:
- INIT.ORA ya da SPFILE dosyasında OPTIMIZER_MODE = RULE değişikliği yapılmalıdır.
-ALTER SESSION SET OPTIMIZER_MODE = RULE komutu sistemde çalıştırılmalıdır.
Cost-Based Optimizer
Cost-Based Optimizer’ın (CBO) Rule-Based Optimizer‘a göre daha kapsamlı ve karışık bir çalışma
prensibi bulunmaktadır. Kullanılacak olan en iyi yöntemi belirlenirken, çeşitli veri tabanı bilgileri (tablo
boyutları, kayıt sayıları, verilerin dağılımı vs.) kullanılmaktadır.
Cost-Based Optimizer‘ının ihtiyacı olan veriyi sağlamak için veri tabanı objelerinin DBMS_STATS
prosedürü kullanılarak analiz edilmeleri ve istatistiklerinin toplatılması gerekmektedir. Eğer bir tablonun
analizi yapılmamışsa, Rule-Based Optimizer‘ın kuralları kullanılarak yolu belirlenir. Aynı sorguda bazı
tablolar analiz edilmiş ve bazıları analiz edilmemiş ise, sistem öncelikli olarak Cost-Based Optimizer‘ını
kullanır. Eğer bu yöntem kullanılacaksa; RDBMS‘de aşağıdaki tanımlamaların yapılması
gerekmektedir:
- INIT.ORA/SPFILE dosyasında OPTIMIZER_MODE = CHOOSE değişikliği yapılmalıdır ve
sorgudaki tablolardan en az bir tanesinin istatistik bilgilerinin mevcut olması gerekmektedir.
-ALTER SESSION SET OPTIMIZER_MODE = CHOOSE komutu sistemde çalıştırılmalıdır ve
sorgudaki tablolardan en az bir tanesinin istatistik bilgilerinin mevcut olması gerekmektedir.
-ALTER SESSION SET OPTIMIZER_MODE = FIRST_ROWS ( veya ALL_ROWS ) komutu
sistemde çalıştırılmalıdır ve sorgudaki tablolardan en az bir tanesinin istatistik bilgilerinin
hesaplanmış olması gerekmektedir.
Explain Plan Tablosu
Oracle‘da bir sorgunun çalışmasının sisteme olan maliyet bilgileri, EXPLAIN PLAN sayesinde
hesaplanabilmektedir. Kullanılan plan tablosunun COST kolonunda sorgunun sisteme olan yükünün
hesaplanmış değeri tutulmaktadır. Kullanılan optimizerin çalışma yolunu değiştirerek ( sorguya
yardımcı ek kurallar koyarak, indeks ekleyerek, indeks kaldırarak, nesnelerin analizini yaparak vs. )
hesaplanan yükteki yükselmeler ve azalmalar gözlemlenir. Böylece sorgunun en uygun maliyeti veren
çalıştırma yöntemi seçilir.
FILTER Korelasyon alt sorgusu gibi eşleşen kayıtları daha kaliteli bir hale getirmek
için sorguda uygulanacak kriterdir.
FULL TABLE SCAN Tablo ilk kayıttan son kayıda kadar taranmakta ve herhangi bir indeks
kullanılmamaktadır.
INDEX (UNIQUE) SQL sorgusu belirli bir değeri aramak için unique ( her satır için ayrı tek
kayıt ) indeks kullanmaktadır.
INDEX (RANGE SCAN) SQL sorgusunda eşitsizlik ya da BETWEEN kriteri kullanılmaktadır.
HASH JOINSQL sorgusundaki tablolar okunur ve hash-key olarak bilinen bir
matematiksel hesaplama ile hafızaya alınırlar.
MERGE JOIN SQL sorgusunda FROM cümleciğinde birden fazla tablo yer aldığı zaman
bu birleştirme yöntemi kullanılır. Oracle, iki sonuç tablosunu birleşen
sütunlar üzerinde biraraya getirerek sıralayacak ve sonra birleşen sütunlar
yardımıyla sonuçları biraraya getirecektir.
NESTED LOOPBu işlem, tabloları birleştirmenin bir başka yöntemidir. İç içe kullanılan
döngü anlamına gelen yöntemde sistem paralel olarak birleştirilen
indeksler üzerinde döngü içinde ilerleyerek sonuca ulaşmaya çalışmaktır.
SQL OPTİMİZASYON ÖNERİLERİ
Birden fazla sorgu kullanılması
X Önerilmez
01
SELECT name
02
03
FROMproducts
04
05
WHEREproduct_id = 1;
06
07
SELECTtype_name
08
09
FROMproduct_type
10
11
WHEREproduct_type_id = 1;
è Önerilir
01
SELECTp.name,
02
03
pt.type_name
04
05
FROMproducts p,
06
07
product_type pt
08
09
WHEREp.product_type_id = pt.product_type_id
10
11
ANDp.product_id = 1;
Bir yerine iki query çalıştırmak her zaman daha çok iş gücüdür.
Tablo kolon tanımları kullanımı
X Önerilmez
01
SELECTp.name,
02
03
pt.type_name,
04
05
description,
06
07
price
08
09
FROMproducts p,
10
11
product_type pt
12
13
WHEREp.product_type_id = pt. product_type_id
14
15
ANDp.product_id = 1;
è Önerilir
01
SELECTp.name,
02
03
pt.type_name,
04
05
p.description,
06
07
p.price
08
09
FROMproducts p,
10
11
product_type pt
12
13
WHEREp.product_type_id = pt. product_type_id
14
15
ANDp.product_id = 1;
Referans verilmezse veri tabanı tüm tablolarda bu alanlar için arama yapmakta ve sorgu daha yavaş
çalışmaktadır.
HAVING yerine WHERE kullanımı
X Önerilmez
1
SELECTproduct_type_id,
2
3
AVG(price)
4
5
FROMproducts
6
7
GROUPBYproduct_type_id
8
9
HAVINGproduct_type_id IN( 1, 2 );
è Önerilir
1
SELECTproduct_type_id,
2
3
AVG(price)
4
5
FROMproducts
6
7
WHEREproduct_type_id IN( 1, 2 )
8
9
GROUPBYproduct_type_id;
İkincisi işlemin başlangıcında kayıtları sınırlarken, ilkinde tüm kayıtlar için AVG çalıştırılmaktadır.
UNION yerine UNION ALL kullanımı
X Önerilmez
01
SELECTproduct_id,
02
03
product_type_id,
04
05
name
06
07
FROMproducts
08
09
UNION
10
11
SELECTproduct_id,
12
13
product_type_id,
14
15
name
16
17
FROMmore_products;
è Önerilir
01
SELECTproduct_id,
02
03
product_type_id,
04
05
name
06
07
FROMproducts
08
09
UNIONALL
10
11
SELECTproduct_id,
12
13
product_type_id,
14
15
name
16
17
FROMmore_products;
UNION ALL her iki sorgu sonucunda tüm kayıtları getirirken, UNION tekrarlanan kayıtları elemektedir.
Bu nedenle, gerçekleşen eleme işleminden dolayı UNION ALL daha hızlıdır ve sistemi yormaz.
IN yerine EXISTS kullanımı
X Önerilmez
01
SELECTproduct_id,
02
03
name
04
05
FROMproducts
06
07
WHEREproduct_id IN(
08
09
SELECTproduct_id
10
11
FROMpurchases );
è Önerilir
01
SELECTproduct_id,
02
03
name
04
05
FROMproducts pr
06
07
WHEREEXISTS (
08
09
SELECT1
10
11
FROMpurchases pu
12
13
WHEREpu.product_id = pr.product_id );
IN bir listede aranan verinin olup olmadığını kontrol eder. EXISTS sadece kayıtların varlığını kontrol
ederken, IN ise gerçek verileri kontrol eder. Alt sorgularda EXISTS daha iyi sonuçlar verdiğinden tercih
edilmelidir.
DISTINCT yerine EXISTS kullanımı
X Önerilmez
1
SELECTDISTINCTproduct_id,
2
3
name
4
5
FROMproducts pr,
6
7
purchase pu
8
9
WHEREpr.product_id = pu.product_id;
è Önerilir
01
SELECTproduct_id,
02
03
name
04
05
FROMproducts pr
06
07
WHEREEXISTS
08
09
( SELECT1
10
Ders Sahibi;
Bilgisayar Dershanesi
Yorumlar
Yorum Yapabilmek İçin Üye Girişi Yapmanız Gerekmektedir.