Ana içeriğe atla

SQL Server Performans İpuçları - 1

Performans kelimesi tek başına şirin görünse de çok göreceli ve değişken bir kavram olup, olumsuz sonuçları gece kâbusumuz haline gelebilir. Basit bir tanım yapacak olsak; “Herhangi bir işlemin beklenenden en az 1 birim fazla doğrulukta, kalitede ve hızda geçekleşmesi, o işin performanslı tamamlandığı anlamına gelir” diyebiliriz.
Bu konuda her türlü bilimsel metriğe sahip olsak da; olaya, yüke, işleme, kişiye ve beklentiye göre değişen sonuçlar hep karşımıza çıkmış ve fenomen haline gelmiş şu cümleyi söylemiş ya da işitmişizdir.
Konu göreceli ve kapsamlı olduğu için çalışma alanı daraltıp, bu bildiride SQL Server’ da [1] T-SQL yazarken ve Indeks kullanırken performansı arttırmak (ya da düşürmemek) için nelere dikkat edilmesi gerektiği anlatılacaktır.
Transact-SQL [2], SQL Server ve istemci (client) arasında iletişimi sağlayan SQL sorgulama dilinin gelişmiş bir versiyonudur. Transact Structured Query Language kelimelerinin kısaltmasıdır. T-SQL kullanarak veri tabanına kayıt eklenebilir, silinebilir, güncellenebilir ya da sorgulama ve raporlama yapılabilir. T-SQL yazarken dikkat edilmesi gereken birçok husus vardır.

T-SQL Sonucunda İhtiyaçtan Fazla Veri Döndürüyor mu?
Bu sorgu sonucunda ne kadar az sonuç kümesi döndürülürse, SQL Server bu veriyi işlemek için o kadar az kaynağa ihtiyaç duyar. Sonuç kümesinde gereksiz veri döndürmek performansı azaltır. Kodlama yapanlar tarafından en çok yapılan hatalar şöyledir:

  • WHERE deyimi içermeyen sorgular. 
  •  WHERE deyimi kullanılması gerekliliğine ilave olarak, WHERE deyimi mümkün olduğu kadar seçici olmalıdır. Örneğin belirli tarihteki kayıtlar isteniyorsa, ay veya yıl için tüm kayıtlar döndürülmemeli. Sadece ihtiyaç olan satırları döndürecek WHERE deyimleri tasarlanmalıdır.
  •   SELECT deyimi, tüm kolonları değil sadece gerekli kolonları içermelidir (Projection). “SELECT *” şeklinde kullanım yanlıştır. 
  •  View’lardan SELECT yapmak yerine, ihtiyaç duyulan verinin direk tablolardan alınması önerilir. Çünkü çoğu view, SELECT deyiminde istenenden yani ihtiyaçtan fazla veri içerir.

Farkında olmadan döndürülen gereksiz veriler, Query Optimizer’ ın indeks taraması yapması yerine tablo taraması yapmasına neden olabilir. Bu da veriyi okumak için fazladan IO gerektirir, SQL Server' ın diğer amaçlar için kullanabileceği buffer cash israf edilir, gereksiz network trafiği meydana gelir.


 İhtiyaç Olmadığı Halde Cursor Kullanılıyor mu?
Cursor kullanımları hem SQL Server hem de uygulama performansını her anlamda yavaşlatır. Cursor’lere bulaşmamak, varsa kurtulmak en akıllıca yoldur. Satır satır işlem yapılması gerekliyse, cursor yerine şu seçeneklerin kullanılması düşünülmelidir;
  •   Geçici (temp) tablo kullanmak 
  •  Türetilmiş tablolar kullanmak
  •   İlişkili alt sorgular kullanmak 
  •  CASE deyimleri kullanmak
  •  Çoklu sorgular kullanmak

Bu maddelerin hepsi cursor yerine geçebilecek seçenekler olup, doğru kullanıldıklarında daha performanslı çalışacaklardır.

UNION / UNION ALL Kullanımları Uygun mu? 
Çoğu kişi UNION ve UNION SELECT çalışma şeklini tam olarak anlamamıştır; bu yüzden SQL Server kaynakları boş yere harcanır. UNION kullanıldığı zaman oluşan sonuç kümesi üzerinde SELECT DISTINCT benzeri işlem gerçekleşir. Diğer bir deyişle UNION, iki benzer sonuç kümesini birleştirerek eş (duplicate) kayıtları tarayıp eleyecektir. Eğer amaç buysa, UNION kullanımı doğru sözdizimidir.Fakat, eş kayıt içermeyecek iki sonuç kümesi birleştirilmek isteniyorsa UNION kullanımı gereksizdir, çünkü olmayacağı bilinen bir eş kayıt tarama işlemi fazladan sistemi yoracaktır. Sonuç olarak, eş kayıt olmayacağı biliniyorsa UNION yerine UNION ALL kullanılması gerekmektedir. UNION ALL iki sonuç kümesini birleştirir ancak eş kayıtları taramaz ve elemez.


DISTINCT Uygun Olarak Kullanılmış mı?
Bazı programcılar SELECT cümlelerine, gerek olsa da olmasa da otomatik olarak DISTINCT deyimini eklerler. Performans açısından DISTINCT deyimi, yalnızca sonuç kümesinde elenmesi gereken eş (duplicate) kayıtlar varsa kullanılmalıdır. Çünkü DISTINCT deyimi kullanımı sonuç kümesi üzerinde önce sıralama sonra da eş kayıtları eleme işlemi gerçekleştirir ve pahalı SQL Server kaynakları kullanır.

GROUP BY Deyimi İyileştirilebilir mi? 

GROUP BY deyimi toplam fonksiyonu ile ve toplam fonksiyonsuz kullanılabilir. Eğer optimum performans isteniyorsa toplam fonksiyonsuz GROUP BY deyimi kullanılmamalıdır. Bu nedenle aynı sonucu elde edebilen DISTINCT seçeneği kullanılabilir ve daha hızlı olur.

Örneğin: 
SELECT OrderID FROM Order_Details WHERE UnitPrice > 10 GROUP BY OrderID 

Yerine DISTINCT ile yeniden yazılabilir:
SELECT DISTINCT OrderID FROM Order_Details WHERE UnitPrice > 10


Yukarıdaki iki sorgu aynı sonucu üretir ancak DISTINCT içeren daha az kaynak tüketir ve daha performanslı çalışır. Aşağıdaki adımlar takip edilerek GROUP BY deyimi hızlandırılabilir:

  •  Sorgudan dönen satır sayısı mümkün olduğunca küçük olmalıdır.
  •   Grup sayısı mümkün olduğunca az olmalıdır.
  •   Gereksiz kolonlar gruplanmamalıdır. 
  •  GROUP BY içeren SELECT deyiminde JOIN varsa, JOIN kullanmak yerine alt sorgu kullanarak sorgu yeniden yazılmaya çalışılmalıdır. Eğer JOIN kullanılması gerekliyse, GROUP BY kolonunun kullanılan diğer kolonlarla aynı tablodan olmasına özen gösterilmelidir.
  •  SELECT deyimine GROUP BY ile aynı kolonları içeren ORDER BY deyimi ile de eklenmesi önerilir. Bu eklenti GROUP BY deyiminin daha hızlı çalışmasını sağlar.
Gereksiz Sıralama İşlemi Yapılıyor mu? 

 SQL Server sıralama işlemi gerçekleştirirken ekstra kaynak kullanır. Sıralama işlemi aşağıdaki T-SQL deyimlerinden biri ile gerçekleşir:
  • ORDER BY
  •   GROUP BY
  •   SELECT DISTINCT
  •   UNION 
  •  CREATE INDEX (Sık çalışmadığı için çok kritik değildir)
Diğer yandan sıralama yükünü azaltmak için dikkat edilebilecek bazı hususlar var:
  • Sıralanacak satır sayısı en aza indirgenmelidir.
  • Sıralanacak kolon sayısı en aza indirgenmelidir. 
  • Sıralanacak kolonların genişliği (fiziksel boyutu) en aza indirgenmelidir. 
  • Karakter veri tipleri yerine sayı veri tiplerine sahip kolonlar sıralanmalıdır.
  • Sıkça sorgulanan belirli kolonlar varsa, bu kolonlara clustered indeks yaratılması önerilir.

SQL Server: http://www.microsoft.com/ sqlserver/en/us/default.aspx 
 http://msdn.microsoft.com/en-us/library/ ms189826(v=sql.90).aspx

Yorumlar

Bu blogdaki popüler yayınlar

PAYTR SANAL POS ASP.NET C# Entegrasyonu

merhaba, bu makalede sizlere PAYTR Sanal pos yapısını .NET üzerinde nasıl çalıştıracağımız ile ilgili bilgi aktarmaya çalışacağım. Ücretsiz başlangıç sağlaması ve sabit ödeme almaması sebebiyle düşük bütçeli e-ticaret yapmak isteyen kişilerin tercih ettiği PAYTR Sanal pos entegrasyonu temelde PHP üzerine kurulmuş. Dolayısıyla .net ile e-ticaret yazmaktaysanız bu sizi bir hayli zorluyor zira firma ile birçok görüşme yapmama rağmen sağlıklı bir .net örneklemesi bulamadım. Baktım olacak gibi değil, sonunda oturdum kendi entegrasyonumu kendim yazdım :). aşağıda detaylı olarak bulabilirsiniz. //using satırlarımızı ekleyelim; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Data; using System.Linq; using System.Net; using System.Security.Cryptography; using System.Text; using System.Web; using System.Web.Script.Serialization; using System.Web.UI; using System.Web.UI.WebControls; //aşağıdaki sabit PAYTR Fonksiyon

ASP.NET Sayfalar arası veri taşıma işlemleri

merhaba; bu yazımda sizlere asp.net üzerinde sayfalar arasında veri taşıma işlemlerinden bahsetmek istiyorum.hepimizin bildiği gibi uygulamarımızda sayfalarımız arası haberleşmeler büyük önem arzetmektedir.bazı sayfalarda bazı işlemlerin yerine getirilebilmesi için diğer sayfalardan gelecek verilere ihtiyaç duyulabilir(GET).ASP.NET üzerinde veri taşıma işlemleri aşağıdaki şekillerde yapılabilir. 1-)QueryString : en yaygın ve basit kullanıma sahip olanıdır.istenilen verileri sayfayı post ettiğiniz zaman yönlendirildiğiniz sayfaya URL üzerinden taşır. Kullanımı : a sayfasından b sayfasına isim taşıyalım. a sayfasında linkinizi şu şekilde değiştirirseniz: Response.Redirect("gidileceksayfa.aspx?isim=can"); Tarayıcınızın URL kısmına baktığınızda: www.siteadi.com/b.aspx?isim=can olarak görürsünüz.a sayfasından veri aktarımı tamamlanmıştır.bundan sonraki adım b sayfasından gelen veriyi almaktan ibarettir.o da şu şekilde yapılır: b sayfasında "isim" adında b

ASP.NET - Aynı anahtara sahip bir girdi zaten var.

Eğer ASP.NET ile uğraşırken böyle bir hata aldıysanız aşağıdaki paragraf tam size göre; " Aynı anahtara sahip bir girdi zaten var."  hatasının sebebi sayfanızdaki birden çok nesne için  ClientIDMode Özelliğini " Static " olarak ayarlamanızdan kaynaklanmaktadır.Normal şartlarda sayfa içerisindeki her kontrolün ID si birbirinden farklı olmalıdır.bu tanımı düzelttiğinizde sorununda çözüldüğünü göreceksiniz.Burdaki problem şu ki visual studio hatayı farklı satırlarda veriyor.buda özellikle ilk defa böyle bir hata ile karşılaşıyorsanız çözümü inanılmaz zorlaştırıyor.