Yazılım

Yazılım Geliştiriciler İçin SQL Performans Arttırma Önerileri

Müşteri ve kullanıcılar her zaman hızlı ve istikrarlı bir uygulama ister. Dolayısıyla, bir uygulamanın veri manipülasyonu sırasında iyi performans sağlayan bir veri tabanı tasarımına sahip olması gerekir. Bununla birlikte, en iyi performansı tanımlamanın basit bir yolu yoktur. Geliştirici olarak, herhangi bir SQL sorgusunun birden fazla yolla yazılabileceğini biliyorsunuzdur, daha iyi sorgu performansı elde etmek için en iyi uygulamaları ve teknikleri takip etmelisiniz. Aşağıda bazılarını paylaşıyorum;

Sadece ihtiyacınız olanı isteyin

Hangi veri tabanı ya da programlama dilini kullandığınız önemli değil, performans için bilmeniz gereken ilk ve en önemli konu; istemci ve sunucu arasındaki veri trafiğinin minimumda tutulması gerektiğidir.

 

Sorgu gönderirken sadece ihtiyacınız olan sütunları isteyin;

Yüzlerce sütun ve milyonlarca satır içeren bir tablo düşünün. Uygulamanız yalnızca birkaç sütuna ihtiyaç duyarsa, tüm verileri sorgulamak mantıklı değildir. Örnek olarak “Ürünler” adındaki bir tablodan [ID] ve [Kodu] alanlarını almak istiyorsanız, sorguda sadece bu alanları talep edin. SELECT * bu senaryo için tamamen gereksizdir ve performansı düşürür.

 

clip_image002

 

Sorgu gönderirken sadece ihtiyacınız olan satırları isteyin;

Sunucudan talep ettiğiniz veriyi mümkün olduğu kadar sunucu tarafında filtreleyin. Sunucudan istemciye transfer edilen veri boyutu ile işlemin tamamlanma süresi genelde doğru orantılıdır. Örnek olarak henüz hiç satılmamış ürünleri bulmaya çalışalım.

Birinci örnekte ürünler ve satışlar tablosundan ürün keylerini okuyup istemci tarafında (C# vb.) karşılaştıralım;

 

clip_image004

 

İkinci örnekte ise tek bir sorgu ile veriyi sunucuda filtreleyerek alalım;

 

clip_image006

 

Sonuçlar sunucu tarafında filtrelenen ve tek bir küme halinde alınan verinin çok daha performanslı çalıştığını göstermektedir.

 

Sunucu ile olan iletişiminizi döngü dışına taşıyın

Sunucuya giden her bir isteğin işlenmesi ve nihayetinde istemciye geri gönderilmesi esnasında kayıp zamanlar oluşur. Bu kayıpları minimumda tutmak için bir önceki konuda bahsedildiği üzere sunucu ile istemci arasındaki trafiği minimumda tutmak gerekir. Bu sebepten döngü içerisinde sorgu gönderme, veri ekleme, güncelleme ve silme işlemlerinden uzak durun.

“İyide zaten döngüyü bunun için çalıştırıyorum, döngü içerisinde veriye ulaşmadan nasıl logic çalıştıracağım? “ diye soruyorsanız; aşağıdaki önerileri dikkatli bir şekilde inceleyin!

 

Select komutu için öneri

Bin adet nesnemiz olduğunu ve her bir nesnenin Test adındaki bir tabloda var olup olmadığını kontrol etmemiz gerektiğini düşünün.

Birinci ve YANLIŞ olan yöntem aşağıdaki örnekte olduğu gibi döngü içerisinde nesne sayısı kadar sorgu göndermektir;

 

clip_image008

 

İkinci ve DOĞRU olan yöntem ise sorguda kullanacağımız parametreleri bir değişkende toplamak ve akabinde tek bir sorgu ile gerekli bilgileri sunucudan almaktır;

 

clip_image010

 

IN operatörü kullanılarak tek bir sorguda alınan verinin ilk örneğe göre çok daha performanslı çalıştığı görülmektedir.

 

Insert komutu için öneri

Bu defa var olan bin adet nesneyi Test adındaki tabloya ekleyelim.

Birinci ve YANLIŞ olan yöntem döngü içerisinde nesne sayısı kadar INSERT komutu çalıştırmaktır;

 

clip_image012

 

İkinci ve DOĞRU olan yöntem ise gerekli parametreleri bir değişkende toplayarak tek bir insert komutu göndermektir.

 

clip_image014

 

Hız farkı ortadadır.

 

Arada bazı yapısal farklılıklar olsa da aynı yöntemler UPDATE ve DELETE komutları içinde kullanılabilir.

 

Count() yerine Exist() kullanın

Veri tabanında bir kaydın bulunup bulunmadığını kontrol etmek isterseniz, COUNT () yerine EXISTS () kullanın. COUNT () tüm tabloyu tararken, EXISTS () koşulunuzla eşleşen satırları sayarak ihtiyaç duyduğu sonucu görür görmez çıkacaktır.

clip_image016

İndeksleri efektif kullanın

Temel terimlerle, indeksler talep edilen kayıtlara hızlı şekilde erişilmesini sağlamak amacıyla kullanılan bir veri yapısıdır. İndeksler aynı zamanda başka sütunların aynı değerleri taşımayacağını garanti edecek birincil anahtar veya benzersiz bir dizin tanımlamak için de kullanılır. İndeksleme bu kısa açıklamayla anlatılamayacak kadar kapsamlı bir konudur. Eğer SQL dünyasında yeni adım attıysanız performans üzerindeki etkisini öğrenmenizi ve indeksler hakkında daha fazla bilgi sahibi olmanızı tavsiye ederim.

·        Sık sık arama işlemlerinizin olduğu tüm tablolarda indeksleri dikkatlice oluşturun.

·        Daha az sayıda arama işlemi, daha fazla sayıda ekleme ve güncelleme işlemi yaptığınız tablolarda indekslerden kaçının.

·        Tam tablo taraması, sorgunun WHERE kısmındaki sütunların kendileriyle ilişkili bir indeks olmadığında gerçekleşir. Bir SQL sorgusunun WHERE kısmında koşullar olarak kullanılan sütunlarda bir indeks oluşturarak tam tablo taramasını önleyebilirsiniz.

·        İndeksleri drop ederek toplu veri yüklemelerini optimize edebilirsiniz. Milyonlarca satır olan bir Log tablosunu hayal edin, bu tabloda bir veya daha fazla indeks olması muhtemel. Toplu veri yüklemesi (INSERT vb.) yapmadan önce indeksleri drop ederek yükleme işlemini hızlandırabilir, işlem bitince tekrar oluşturabilirsiniz.

 

İndekslerdeki parçalanmalara dikkat edin

Bir veri tabanı INSERT, UPDATE veya DELETE komutları ile sık sık güncellendiğinde, zamanla parçalanma oluşabilir. Veri tabanı indeksleri parçalanırsa, SQL sorgu iyileştiricisi bir sorguyu çözümlemek için indeks kullanırken uygun olmayan bir yürütme planı seçebilir. Bu genel sorgu performansını etkiler ve bir sorgunun normalden daha yavaş çalışmasıyla sonuçlanır.

Aşağıdaki script çalıştırıldığı veri tabanındaki parçalanmış indeksleri raporlar. Bu scripti kullanarak hangi indekslerde parçalanma olduğunu öğrenebilirsiniz. Parçalanan indekslerin tekrar organize edilmesi için bir bakım planı oluşturabilir veya bu linkteki yöntemi deneyebilirsiniz.

clip_image018

Diğer öneriler

·        Uygun veri türü ’nü seçin. Örneğin string depolamak için text veri türünün yerine varchar kullanın. Büyük verileri (8000’den fazla karakter) depolamanız gerektiğinde text veri türünü kullanın.

·        Unicode karakter saklamanız gerekmiyorsa nchar ve nvarcharlardan kaçının, çünkü her iki veri türü de aslında char ve varchar dır ancak iki kat fazla yer kaplar.

·        Sabit uzunluklu alanda NULL kullanmaktan kaçının. NULL gereksinimi olması durumunda, NULL için daha az değişken uzunluklu (varchar) alanı kullanın.

·        Having kullanmaktan kaçının. Bir toplama işleminin sonucunu filtrelemek istiyorsanız kullanın.

·        Kümelenmiş (Clustered) ve Kümelenmemiş (Non-Clustered) indeksler oluşturun.

·        Kümelenmiş (Clustered) indeks kullanılan alanlar kümelenmemiş (Non-Clustered) dizinde de kullanılabilir olduğundan kümelenmiş dizini küçük tutun.

·        Kullanılmayan İndeksleri kaldırın.

·        Karakter yerine tamsayı değerleri olan sütunlar üzerinde indeksler oluşturmak daha iyidir. Tamsayı değerleri, karakter değerlerinden daha az ek yük kullanır.

·        Alt sorgular yerine Join kullanın.

·        Join içeren sorgularda tablolarının boyutunu sınırlamak için WHERE ifadelerini kullanın.

·        Bir tabloya ekleme yaparken TABLOCKX ve birleştirirken TABLOCK kullanın.

·        Herhangi bir tablodaki verileri sorgularken WITH (NOLOCK) kullanın.

·        Kilitlenme durumundan kaçınmak için SET NOCOUNT ON ve TRY CATCH kullanın.

·        Cursor genelde yavaş olduğu için kaçının.

·        Temp tablosu yerine Tablo değişkenini kullanın. Temp tablolarının kullanılması TempDb veritabanı ile etkileşime geçer.

·        Mümkünse UNION yerine UNION ALL kullanın.

·        Sık kullanılan veriler ve daha karmaşık sorgular için Stored Procedure kullanın.

·        Transaction tablolarda kilitlenmelere neden olabileceğinden transactionları mümkün olduğunca küçük tutun.

 

 

Sonuç: SQL sorguları yazabilmek veri işleyen bir uygulama oluşturmak için yeterli gibi görünse de, asıl macera uygulama belirli bir kullanıcı sayısına ve veri tabanı belirli bir büyüklüğe ulaşınca başlar. Bu sebepten verilerin nasıl depolandığını anlayarak en uygun tasarımı ve sorguları oluşturmak önemlidir. Bu makalede önerilen teknikleri uygulamanızın ihtiyaçlarını göz önünde bulundurarak test etmenizi tavsiye ederim. Umarım faydasını görürsünüz.

 

Bir sonraki makalede görüşmek üzere.

Hoşça kalın.

 

 

 

İlgili Makaleler

Bir Yorum

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Başa dön tuşu