9 Şubat 2010 Salı

SQL Sorgularında "IN" - "NOT IN" Kullanımı

sqlservercentral.com'da okuduğum bir yazıyı burada paylaşmak istedim.

Konu sorgularımızda IN ve NOT IN kıyaslamalarını kullanmamız.
Aslında konuyu ikiye ayırmakta fayda var, ilk olarak performans konusunu ele almamız uygun olacaktır. Hemen en önemli kısım ile başlayalım; NOT IN kullanılan sorgularda INDEX kullanılmaz :)

Index'in mantığı gereği, bu indexte olmayanları bul dediğimizde, kayıtların sıralı olmasının bize bir faydası olmayacaktır. Tüm tablonun taranması gerekecektir. Konu ile çok ilgisi olmasada benzer bir durumu daha söylemekte fayda var. LIKE '%KRITER' şeklinde bir arama yaptığımızda Index'imizin bize faydası olmayacaktır. Bunun sebebi Index'lerin sıralı bir şekilde tablomuzda barınıyor olması, biz ilk karakteri bilemezsek bu sıranın bize faydası olmayacaktır. Bunu baş harfini bilmediğimiz bir kelimeyi sözlükte aramak olarak düşünebilirsiniz, fihristi kullanma imkanımız olmayacak, tüm kelimelere teker teker bakmamız gerekecektir.
NOT LIKE, <> gibi kriterlerde de Index kullanımı aynı sebepler yüzünden olmayacaktır. 

Hem NOT LIKE hemde '%KRITER' şeklindeki bir sorguda, SQL motoru tarafından kafamıza şişe fırlatılması ihtimali yüksektir :)

Bu sebeplerden olumsuz kriter kullanımlarımını sadece zorunlu durumlardaki sorgularımızda kullanmalıyız. Sistemi incelerken kontrollü bir şekilde bu sorguları kullanabiliriz. Ancak özellikle raporlarda bu eşitsizlik kontrollerinin kullanımı, ve özellikle büyük tablolarda kullanımı bizi çok ama çok zora sokacaktır. Kesinlikle bu tür kullanımlardan uzak durmamız gerekiyor.

Konunun bu kısmı nispeten biliniyordu, ancak bana asıl ilginç gelen NOT IN kullanımlarında dönen cevapların belirsizliği oldu, bunu ilgili sayfadaki arkadaşımız çok güzel bir örnekle açıklamış aynen iletiyorum.

IN kullanımlarında aslında arka planda şu şekilde bir sorgu çalışmış oluyor "WHERE myvalue = 'A' OR myvalue = 'B' OR myvalue = NULL"
Burada bir OR işlemi olduğundan dolayı, beklemediğimiz bir sonuç ile karşılaşmamız olası değil.


NOT IN kullanımlarında ise arka planda aslında olan 'WHERE myvalue <> 'A' AND myvalue <> 'B' AND myvalue <> NULL “

İşte burada bir AND işlemi var, NULL olan alanlar belirsiz olduklarından dolayı, sorgu sonucunda beklemediğimiz bir sonuç kümesi ile karşılaşmamız olası.

A IS NULL ve A = NULL arasında fark olduğunu unutmamak gerekli. Bir çok kişi bu basit hatadan dolayı saatlerce sorgusundaki hatayı arayabilir -ben çok aradım-.


Buradaki kıyaslama için SET ANSI_NULLS = ON/OFF durumu önemlidir. Uygun olan kullanım genelde ON şeklindedir. Yukarıda yazdığım örnekte bu ayarın ON durumunda olduğunu varsaydım.

Hiç yorum yok:

Yorum Gönder