SQL Server Execution Plan Mimarisi Kitabımız Yayınlandı!!!

SQL Server ile çalışırken dikkat ettiğimiz en önemli konulardan biri SQL Server’da çalıştırdığımız sorguların performansıdır. Yazdığımız sorguların performanslı bir şekilde çalışması bizler için oldukça önem arz etmektedir. Bu nedenle çoğu uygulama geliştirici ve veritabanı yöneticisi tarafından çalıştırılan sorguların hangi çalıştırılma yöntemini kullanarak işleme alındığını incelemek ve buna uygun müdahalelerde bulunmak gerekebilir. İşte bu nedenle SQL Server’ın bir sorguyu nasıl çalıştıracağının veya nasıl çalıştırdığının yöntemi Execution Plan olarak bilinmektedir. Bu kitabımızda SQL Server’a ait Execution Plan Mimarisi’ni detaylı olarak ele aldık. Kitabın yazılmasında hem arkadaşım hem de meslektaşım olan İsmail Adar ile birlikte rol almak benim için büyük bir keyifti. Umarım okurken sizler de aynı keyfi alırsınız…

 Kitabı aşağıdaki linkten indirebilirsiniz. Keyifli okumalar…

SQL Server Execution Plan Kitabı

kitap kapak

Top N Sorguları İle Çalışmak (MS SQL Server vs Oracle)

Günümüzde en çok kullanılan İlişkisel Veritabanı Yönetim Sistemleri (RDBMS)’ nin başında  Microsoft SQL Server ve Oracle gelmektedir. Her iki veritabanı yönetim sistemi de şirketler tarafından sıklıkla tercih edilebilmektedir. Bir şirket kullanmakta olduğu veritabanı yönetim sistemini diğer bir veritabanı yönetim sistemine taşımak isteyebilmektedir. Bu gibi migration durumlarında veritabanını kullanan uygulamaların, migration işleminden etkilenmeden işleyişini devam ettirmesi gerekmektedir. Bu gibi durumlarda veritabanında tutulan veriler diğer sisteme taşınsa bile, veritabanı yönetim sistemine bağlı olarak uygulamaların veritabanına gönderdiği komutların da (DML, DDL vs) bu migration işlemi sırasında elden geçirilmesi gerekebilecektir. Her ne kadar Oracle ve MS SQL Server arasında, kullanılan SQL komutları ve dil yapısı arasında temel olarak çok fazla fark olmasa bile, bazı işlemleri her iki sistemde farklı komutlar ve yollar kullanarak elde etmek mümkün olabilmektedir. Bu yazımızdan itibaren belirli aralıklarla MS SQL Server‘da kullanılan T-SQL dili ve Oracle‘da kullanılan SQL ve PL/SQL dilleri üzerinde farklı şekillerde yapılabilecek işlemleri ele alıyor olacağız.

İlk olarak bu makalemizde, veritabanındaki tablolardan döndürülecek kayıtların belirli bir sayıda sınırlanmasının her iki sistemde nasıl gerçekleştirilebileceğini ele alıyor olacağız. Bu gibi sorgulara örnek olarak,

  • en son sipariş veren son 10 müşteri,
  • en son kayıt olan 5 öğrenci,
  • satılan ürünler içerisindeki en pahalı 3 ürünün tespit edilmesi,
  • bugüne kadar en çok sipariş veren ilk 100 müşterinin tespit edilmesi

gibi durumlar verilebilir. Görüldüğü üzere bu tip sorgularda hem bir şarta bağlı olarak sıralama işlemi gerçekleştirilmekte, hem de bu sıralamaya bağlı olarak döndürülecek satır sayısına bir limit, sınır verilmektedir. Literatürde bu tip sorgulara Top N sorguları denilmektedir. Şimdi bu tip sorguların her iki veritabanı yönetim sisteminde nasıl ele alınacağını hep birlikte inceleyelim:

Microsoft SQL Server:

MS SQL Server’da Top N sorgularını yazmak oldukça basittir. Bu işlemi gerçekleştirebilmek için SQL Server‘da bulunan ve SELECT komutu içinde kullanılabilen TOP ifadesi vasıtasıyla sonuç setinde döndürülecek kayıt sayısı sınırlandırılabilir. Tabi ki TOP operatörünün mantıklı bir şekilde çalışabilmesi için sorgunun ORDER BY ile istenilen şarta bağlı bir şekilde sıralanması gerekmektedir. Aşağıdaki örneği hep beraber inceleyelim:

SELECT TOP 10 SalesOrderID, CustomerID, OrderDate, SubTotal
FROM Sales.SalesOrderHeader
ORDER BY OrderDate desc

Yukarıdaki SQL sorgusunda en son verilen 10 siparişe ait detaylar getirilmektedir. Görüldüğü üzere MS SQL Server üzerinde bu işlemi yapabilmek için ORDER BY ile veriler OrderDate kolonuna göre büyükten küçüğe sıralanmış ve SELECT komutunun yanına TOP 10 ifadesi eklenerek getirilecek sonuç sayısının 10 ile sınırlandırılması sağlanmıştır. Sorgunun çıktısı aşağıdaki gibidir:

TopN_1

MS SQL Server içerisinde TOP ifadesinin yanına yukarıda olduğu gibi sadece sayı verildiğinde, döndürülecek olan satır sayısını rakamsal olarak sınırlandırmış olursunuz. Bu kullanım ile beraber TOP ifadesinin tablodaki satır sayısının belirli bir yüzdesi kadar sonuç döndürmesi için PERCENT ifadesi eklenebilmektedir. Bu durumda sorgu aşağıdaki gibi olacaktır:

SELECT TOP 20  PERCENT SalesOrderID, CustomerID, OrderDate, SubTotal
FROM Sales.SalesOrderHeader
ORDER BY OrderDate desc

MS SQL Server içerisinde TOP ifadesi ile beraber kullanılabilen diğer seçenekleri (WITH TIES gibi) ve SQL Server 2012 ile beraber gelen ve TOP işlemini biraz daha genişleten ve sayfalama imkanı yapılmasına olanak sağlayan OFFSET – FETCH komutlarını başka bir yazıya bırakarak TOP N sorgularının Oracle‘da nasıl yapılabileceğine de bir göz atalım:

Oracle:

Benzer bir şekilde üniversite öğrencilerinin kayıtlarının tutulduğu bir tablo üzerinde en son kayıt olan 10 öğrencinin getirilmesi istenildiğinde, Oracle’da TOP operatörü olmadığı için farklı bir yöntem kullanılarak bu ihtiyaç karşılanabilmektedir. Burada ROWNUM kullanılarak döndürülecek kayıt sayısı sınırlandırılabilmektedir, ancak aynı sorgu içerisinde ORDER BY ile sıralama şartı verilmesine rağmen WHERE komutu Oracle optimizeri tarafından daha önce çalıştırıldığı için istenilen sonuç tek bir sorguda elde edilememektedir. Aşağıda bu örnek (yanlış sonuç üretiyor…) görülebilir:

  SELECT student_ıd,
          fırst_name,
          last_name,
          regıstratıon_date
  FROM student
  WHERE ROWNUM <= 10
  ORDER BY regıstratıon_date DESC;

Buradaki SQL sorgusunda öncelikle WHERE komutu çalıştırılarak getirilen kayıt sayısı 10 ile sınırlandırılıyor, ardından da ORDER BY ile bu 10 kayıt büyükten küçüğe sıralandırılıyor. Böyle bir durumda istenilen sonuç elde edilemeyecek ve sonuç seti bizim açımızdan hatalı olacaktır:

TopN_3

Yukarıda üretilen ve bizim açımızdan hatalı olan sonuçları düzeltebilmek ve gerçekten en son kayıt olan 10 öğrenciyi ele alabilmek için ORDER BY komutunun önce çalıştırılması ve ardından WHERE ile kayıt sayısının sınırlandırılması gerekmektedir. Bunu gerçekleştirebilmek için de bir subquery (inline view) kullanarak önce sıralama işlemi yapılmakta ve ardından da dış sorguda döndürülecek olan sonuç seti sınırlandırılabilmektedir.

Sorgunun doğru hali aşağıdaki gibidir:

SELECT *
FROM
  (SELECT student_ıd,
          fırst_name,
          last_name,
          regıstratıon_date
  FROM student
  ORDER BY regıstratıon_date DESC
  )
WHERE ROWNUM <= 10;

Bu şekilde çalıştırılan bir sorgunun ardından tablodaki kayıtlar öncelikle registration_date kolonuna göre büyükten küçüğe sıralanacak, ardından bu iç sorgudan dönen değerler dış sorguda yer alan ROWNUM filtresi ile belirli bir adette döndürülmesi sağlanacaktır. Sorgudan dönen doğru sonuç seti aşağıdaki gibidir:

TopN_2

Oracle 11 g ve önceki versiyonlarında bu gibi TOP N sorgulama işlemleri sadece ROWNUM kullanılarak değil, aynı zamanda RANK, DENSE_RANK, ROW_NUMBER gibi fonksiyonlar vasıtasıyla da yazılabilmektedir. OVER cümlesi ile beraber kullanılan bu fonksiyonları başka bir makalemizde ele alıyor olacağız.

Ayrıca Oracle 12 c ile beraber gelen yeni bir özellik ile TOP N sorguları çok daha kolay bir şekilde yazılabilmektedir. Yukarıda yazılan sorguyu Oracle 12 c ile beraber aşağıdaki şekilde çok daha kolay bir şekilde yazabileceksiniz:

  SELECT student_ıd,
          fırst_name,
          last_name,
          regıstratıon_date
  FROM student
  ORDER BY regıstratıon_date DESC
  FETCH FIRST 10 ROWS ONLY;

Görüleceği üzere MS SQL Server ile Top N sorguları, özellikle Oracle 11 g ve öncesiyle kıyaslandığında çok daha kolay bir şekilde yazılabilmektedir. Oracle 12 c ile gelen OFFSET-FETCH komutu ile Top N sorguları artık Oracle'da da daha kolay ele alınabilmektedir. Faydalı olması dileğimle...

Yazı hakkındaki görüş, öneri ve yorumlarınızı bildirebilirsiniz. Bir sonraki yazımızda görüşmek üzere...

Yazar: Abdullah ALTINTAŞ

Neden Oracle Oluşturulan İndex’i Kullanmıyor? (Oracle Function-Based Index Oluşturma)

İlişkisel Veritabanı Yönetim Sistemleri (RDBMS) ‘nde veriler tablolarda tutulmaktadır ve tablolar arasında da Primary Key – Foreign Key kullanılarak ilişkiler tasarlanmaktadır. Kullanıcılar veritabanındaki tablolarda bulunan ilgilendikleri verileri SQL sorguları vasıtasıyla çekmektedirler. Yazılan SQL sorgusuna bağlı olarak, kullanılan veritabanı yönetim sistemi optimizerı, veriye bütün tabloyu baştan sona tarayarak (table scan / full access) veya  ilgili kolonlar üzerinde veriye erişimi hızlandırmak için oluşturulan index sayfalarını okuyarak (index seek / index scan) erişebilmektedir. Çoğu durumda index sayfalarının okunmasıyla veriye erişim çok daha hızlı gerçekleştirilmektedir. Bu sebeple veritabanı geliştiricileri veya veritabanı yöneticileri optimize etmek istedikleri sorguları inceleyerek belirli kolonlara indexler oluşturarak sorgu sürelerini azaltmayı hedeflemektedirler.

İndex oluşturulan kolonlar SQL sorgusunun WHERE kısmında yalın haliyle kullanıldığında (herhangi bir function veya expression içerisinde kullanılmadığında), ilgili sistemin optimizerı oluşturulan indexin sayfalarından okuma yaparak veriye hızlıca erişebilir. Ancak index oluşturulan kolonlar WHERE koşulu içerisinde yalın haliyle kullanılmayıp, örneğin bir fonksiyon içerisinde kullanıldıysa, ilgili optimizer veriye erişebilmek için var olan indexi kullanamaz hale gelir.

Genellikle veritabanı geliştiricilerinin başına gelen ve “Neden oluşturmuş olduğum index optimizer tarafından kullanılmıyor?” sorusunun muhtemel yanıtlarından birisi yukarıda bahsedilen durumdur. Oracle, böyle bir durumla karşılaştığınızda sizlere index oluşturulmak istenilen kolonu yalın haliyle indexleme imkanının yanında bir de kullanılan fonksiyon ile beraber ayrıca index oluşturma imkanını da sunmaktadır. Bu şekilde oluşturulan index türüne Oracle’da Function-Based İndex adı verilmektedir. Function-Based İndex‘ler vasıtasıyla tablolara ait kolonlar Oracle fonksiyonları ile beraber indexlenebilmektedir. Genel olarak anlattığımız konuyu bir de örnekle inceleyelim:

Aşağıda Oracle SQL Developer aracı kullanılarak bir SQL sorgusu çalıştırılmaktadır:

SELECT *
FROM grade,
  student,
  instructor,
  zipcode
WHERE UPPER(grade_type_code) = 'PJ';

Yukarıdaki SQL sorgusunda course, instructor, zipcode ve grade tabloları cross join olacak şekilde bağlanmış ve sorgunun WHERE filtresi kısmında grade_type_code değeri ‘PJ’ olan kayıtlar getirilmek istenmiştir. Ancak ilgili tabloda tutulan değerlerin küçük/büyük harflerle birlikte tutulabileceği göz önüne alınarak grade_type_code kolonu UPPER fonksiyonu ile beraber kullanılarak her çeşit tutulabilen değerlerin getirilmesi garanti altına alınmıştır.

Bu şekilde oluşturulan bir sorgu için sadece grade_type_code kolonu üzerine DENEME_1 isminde bir index oluşturalım:

CREATE INDEX DENEME_1 ON GRADE (GRADE_TYPE_CODE);

Ardından sorgumuzun explain planını inceleyerek Oracle optimizerının DENEME_1 ismindeki indexi kullanıp kullanmadığına bakalım:

FB_index_1

Explain Plan çıktısından görülebileceği gibi Oracle optimizerı grade tablosuna DENEME_1 index sayfalarını okuyarak değil, FULL TABLE ACCESS yöntemini kullanarak bütün tabloyu baştan sona okumayı tercih etmiş gözüküyor. grade_type_code kolonunda index oluşturulmasına rağmen bu yöntemi seçmesi ve indexi kullanamamasının sebebi, grade_type_code kolonunun UPPER fonksiyonu içerisinde kullanılmış olmasıdır.

Bu durumda Oracle Function-Based İndex oluşturularak bu sorunun üstesinden gelinmesi sağlanabilir. Aynı sorguyu bir de aşağıdaki DENEME_2 isminde bir Function-Based Index oluşturarak çalıştıralım ve explain planını inceleyelim:

CREATE INDEX DENEME_2 ON GRADE (UPPER(GRADE_TYPE_CODE));

Şu an grade tablosundaki grade_type_code kolonu üzerinde hem DENEME_1 isminde bir normal index bulunmakta, hem de DENEME_2 isminde bir function based index bulunmaktadır. Sorgunun tekrar çalıştırılmış ve explain planının oluşturulmuş hali aşağıdaki gibi olacaktır:

FB_index_2

Görüldüğü gibi Oracle SQL optimizerı DENEME_2 ismindeki function-based indexi kullanarak veriye erişmiş durumdadır. Aşağıda her iki durumda oluşturulan explain planların karşılaştırılması verilmiştir:

FB_index_3

Oracle veritabanlarında kullanılan sorgular için funciton-based index oluşturulması görüldüğü gibi oldukça basit bir işlemden ibarettir. Normal bir index oluşturur gibi indexe bir isim verilmekte, hangi tablonun hangi kolonu üzerinde index oluşturulacağı belirtilmekte, farklı olarak sadece bu kolonu ilgili fonksiyon ismi ile beraber indexleneceği bilgisi verilmektedir. İşinize yaraması dileklerimle bir sonraki yazımızda görüşmek üzere…

Yazar: Abdullah ALTINTAŞ

64 bit Windows İşletim Sistemlerine Oracle 11g Database XE Kurulumu Hatasının Çözümü

Oracle 11g Database Express Edition (XE) kurulumu için, Oracle sitesinden kurulum dosyasını indirmek istediğinizde, Windows işletim sistemleri üzerinde sadece 32-bit işletim sistemleri için kurulumun desteklendiği ve Windows 64-bit sistemlerde desteklenmediği yazısını görebilirsiniz. Peki 64-bit Windows işletim sistemi kurulu olan kullanıcılar bu durumda ne yapmalı? Bu makalemizde sizlere bu işlemin nasıl gerçekleştirilebileceğini aktarıyor olacağım.

  • Öncelikle Oracle 11g Database XE kurulum dosyasını Oracle sitesi üzerinden indiriyoruz ve kurulumu başlatıyoruz. Eğer işletim sisteminiz 64-bit ise, kurulum devam ederken,

“The installer is unable to instantiate the file C:\Users\ … … \KEY_XE.reg. This file does not appear to exist.”

gibi bir hata ile karşılaşacaksınız. Bu hata mesajı karşınıza çıktığında, hata mesajı kutusunu kapatmadan, Başlat menüsü arama kutusuna regedit yazıp registry editörünü açıyoruz.

  • Sol taraftaki menüden “HKEY_CLASSES_ROOT/Installer/Products/266B7A….. /SourceList/Media” kısmına geliyoruz. Karşımıza aşağıdakine benzer bir görüntü çıkacaktır.

RegeditEski

  • Sağ tarafta bulunan “1”  bölümü üzerine sağ tıklayarak Modify seçeneğini seçiyoruz.
  • Hata mesajı aldığımız ekrandaki dosyanın yolunu kopyalayıp, sonundaki KEY_XE.reg kısmı olmayacak şekilde, modify ettiğimiz değer bölümündeki Disk1;1 yazan kısım ile değiştiriyoruz.
  • KEY_XE.reg çıkartıldıktan sonra dosya yolu;   C:\Users\Domain Adı\AppData\Local\Temp\{rakanmlar ve karakterler}\     gibi olmalıdır.
  • Gerekli değişikliği yaptığınızda registry ekranında aşağıdakine benzer bir ekran ile karşılaşmanız gerekmektedir.

RegeditYeni

  • Ardından registry ekranını kapatıp Oracle 11g XE Database kurulumu sırasında aldığınız hata mesajına OK diyerek kapatabilirsiniz. Eğer tekrar hata veriyorsa bir kez daha OK butonuna tıklandığında hata mesajı kapanıp kuruluma devam edilecektir.
  • Kurulum tamamlandığında herhangi bir client tool ile Oracle Database 11g XE (Express Edition) veritabanına bağlanabilir ve yapmak istediğiniz işlemleri gerçekleştirebilirsiniz.

Yazı hakkındaki görüş ve önerilerinizi bana iletebilirsiniz. Bir başka makalede görüşmek üzere…

Yazar: Abdullah ALTINTAŞ