İçeriğe geç

QueryMultiple ile Birden Fazla Sorgu: Veri Denizi Birleştirmenin Gizemi

Şimdi bu işlere girişmeden önce, hani bazen bir veritabanına bağlanıp saatlerce sorgu yazmaya çalışırsın ya, işte o anlarda aklına gelir: Keşke tek seferde birkaç farklı sorguyu çalıştırıp sonuçları bir arada görebilsem!

Gerçi eskiden olsa hemen SQL Server Management Studio’yu açar, birkaç tane tablo birleştirme sorgusu yazar, sonra da onları bir şekilde bir araya getirmenin peşine düşerdim. Ama şimdi işler biraz daha farklılaştı, hele ki bulut tabanlı servisler, mikroservisler falan derken olaylar iyice değişti.

Bu QueryMultiple denen olay da tam olarak burada devreye giriyor aslında. Düşünün ki bir web uygulamanız var ve kullanıcılar sitede gezerken birden fazla kaynaktan veri çekmesi gerekiyor. Mesela bir ürün listesi göstereceksiniz ama bu ürünlerin hem stok bilgisi ayrı bir veritabanında, hem fiyat bilgisi bambaşka bir serviste, hem de yorumları başka bir yerde. Eskiden bunları tek tek çekip sonra kod tarafında birleştirirdiniz, değil mi?

İşte tam da bu noktada QueryMultiple gibi yetenekler hayat kurtarıcı olabiliyor. Bu özellik sayesinde, tek bir istekte birden fazla sorguyu aynı anda çalıştırıp, sonuçlarını topluca alabiliyorsunuz. Düşünsenize, hem daha az ağ trafiği, hem daha hızlı cevap süresi. Ne güzel değil mi?

Bu arada, bu olayın tam olarak nasıl çalıştığına dair detaylar biraz teknikleşebilir ama genel mantığı oldukça basit. Siz istediğiniz sorguları bir liste halinde sunuyorsunuz, sistem de bunları eş zamanlı olarak çalıştırıyor. Sonuçlar geldiğinde de size hepsini bir arada teslim ediyor. Yani şey gibi, bir restorana gidiyorsun ve hem ana yemeğini hem de tatlını aynı anda sipariş ediyorsun, garson da hepsini aynı anda getiriyor. İşte bu da öyle bir şey.

Veritabanı Sorgularını Birleştirmenin Gücü

Tabi bu dediklerim sadece veritabanları için geçerli değil. Bu mantık, farklı API’lerden veri çekmek, dosyalardan okumak gibi birçok senaryoda da kullanılabilir. Önemli olan, birden fazla kaynaktan veri toplama ihtiyacınızın olması.

Mesela bir raporlama sistemi düşünün. Bu raporun hem satışları, hem stokları, hem de müşteri bilgilerini içermesi gerekiyor. Eğer bu veriler farklı sistemlerdeyse, tek tek sorgu çekmek yerine QueryMultiple ile hepsini tek seferde almak, hem raporun hazırlanma süresini kısaltır hem de sunucular üzerindeki yükü azaltır.

Bu arada, bu özelliğin hangi veritabanı veya framework’te olduğunu merak edenler için söyleyeyim; bu daha çok ORM (Object-Relational Mapping) dediğimiz araçların bir özelliği olarak karşımıza çıkıyor. Mesela Dapper gibi hafif ve hızlı ORM’ler bu tür gelişmiş sorgu yeteneklerini destekleyebiliyor. Hatta bazen doğrudan veritabanı sürücülerinin kendisi de bu tür senkron olmayan veya toplu sorgu işlemlerini destekleyebiliyor.

Aslında bu işin en can alıcı noktası, eş zamanlılık ve paralel işlem gücünü kullanmak. Yani siz bir sorguyu beklerken, diğer sorgu da arka planda çalışıyor. Bu da toplam işlem süresini ciddi anlamda kısaltıyor. Eskiden olsa, tek tek sorgu çekip sonra kod içinde `Task.WhenAll` falan kullanırdım, ama bu tür hazır çözümler işi çok daha kolaylaştırıyor. Sanırım bu yüzden birçok modern framework bu özelliği desteklemeye başladı.

Pratik Uygulama: Kod Örneğiyle Görelim

Şimdi lafı uzatmadan, gelin bu işin nasıl olduğunu basit bir C# koduyla görelim. Diyelim ki hem kullanıcı bilgilerini hem de o kullanıcının siparişlerini tek bir sorguda çekmek istiyoruz. Bu senaryoda, iki farklı tabloya erişmemiz gerekecek.

Şimdi ilk olarak, hatalı veya daha ilkel bir yaklaşımla, bu işi nasıl yapardık ona bakalım. Tek tek sorgu çekmek ve sonra bunları birleştirmek gibi düşünebilirsiniz:

// YANLIŞ YAKLAŞIM – Tek Tek Sorgu Çekme

public async Task<KullaniciVeSiparisler> GetKullaniciVeSiparisleriAsync_Yanlis(int kullaniciId, IDbConnection dbConnection)

{

var kullanici = await dbConnection.QueryFirstOrDefaultAsync<Kullanici>("SELECT * FROM Kullanicilar WHERE Id = @Id", new { Id = kullaniciId });

var siparisler = await dbConnection.QueryAsync<Siparis>("SELECT * FROM Siparisler WHERE KullaniciId = @KullaniciId", new { KullaniciId = kullaniciId });

// Sonuçları manuel olarak birleştir

var result = new KullaniciVeSiparisler

{

Kullanici = kullanici,

Siparisler = siparisler.ToList()

};

return result;

}

Gördüğünüz gibi, önce kullanıcıyı çekiyoruz, sonra siparişleri çekiyoruz. İki ayrı veritabanı sorgusu. Bu gayet çalışır bir yöntem tabi, ama ya daha fazla veri çekmemiz gerekirse? Her seferinde yeni bir sorgu, yeni bir `await`… Zamanla bu işler uzar gider.

Şimdi gelelim daha akıllıca olana, yani QueryMultiple özelliğini kullanarak bu işi tek seferde nasıl yapacağımıza:

// DOĞRU YAKLAŞIM – QueryMultiple Kullanımı

public async Task<KullaniciVeSiparisler> GetKullaniciVeSiparisleriAsync_Dogru(int kullaniciId, IDbConnection dbConnection)

{

var sql = @"

SELECT * FROM Kullanicilar WHERE Id = @Id;

SELECT * FROM Siparisler WHERE KullaniciId = @KullaniciId;

";

using (var multi = await dbConnection.QueryMultipleAsync(sql, new { Id = kullaniciId, KullaniciId = kullaniciId }))

{

var kullanici = await multi.ReadFirstOrDefaultAsync<Kullanici>();

var siparisler = await multi.ReadAsync<Siparis>();

return new KullaniciVeSiparisler

{

Kullanici = kullanici,

Siparisler = siparisler.ToList()

};

}

}

İşte bu kadar! Sadece tek bir SQL komutuyla, istediğiniz kadar sorguyu çalıştırma imkanınız oluyor. Dapper’ın `QueryMultipleAsync` metodu sayesinde önce tüm sorguları tek bir string’de topluyorsunuz, sonra da `multi.ReadFirstOrDefaultAsync` ve `multi.ReadAsync` gibi metotlarla sonuçları sırayla alıyorsunuz. Bu, gerçekten de inanılmaz bir performans artışı sağlıyor.

Bu arada, unutmamak lazım ki, sorguların sırası çok önemli. Yani siz önce kullanıcıyı çekmek istiyorsanız, SQL kodunuzda da önce kullanıcıyı tanımlayan sorguyu yazmalısınız. Aksi takdirde, `multi.ReadFirstOrDefaultAsync` ilk sorgunun sonucunu değil, ikinci sorgunun sonucunu getirebilir. Bu da işleri karıştırır tabi 🙂

Neticede Ne Fayda Sağlıyor?

QueryMultiple kullanımı, özellikle çok sayıda kaynaktan veri çekmeniz gereken senaryolarda size büyük avantajlar sağlar. Hem geliştirme süresini kısaltır, hem de uygulamanızın performansını artırır. Düşünün ki büyük bir e-ticaret sitesinde, bir ürün detay sayfasını yüklerken hem ürün bilgilerini, hem benzer ürünleri, hem de stok durumunu çekmeniz gerekiyor. Bu tür durumlarda QueryMultiple gerçekten bir kurtarıcı olabilir.

Ayrıca bu teknoloji, sadece veritabanı sorgularıyla sınırlı kalmıyor. Farklı API’lerden eş zamanlı olarak veri çekmek için de kullanılabiliyor. Bu da mikroservis mimarilerinde oldukça sık karşılaşılan bir durum. Yani bir ana servis, birden fazla mikroservisten veri toplamak istediğinde bu yöntem çok işe yarar. Hani derler ya, az çabayla çok iş yapmak, işte bu tam olarak öyle bir şey.

Sonuç olarak, eğer veri erişim katmanınızda performans artışı ve daha temiz kod yazma ihtiyacınız varsa, QueryMultiple gibi özellikleri mutlaka araştırmalısınız. Bu, kodunuzu hem daha verimli hem de daha okunabilir hale getirecektir. Deneyin derim, farkı siz de göreceksiniz. Ne güzel değil mi?

Bir yanıt yazın

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.