Veritabanı bağlantısı oluşturma - Bir kez mi, yoksa her sorgu için mi?


101

Şu anda web sayfam ilk yüklendiğinde bir veritabanı bağlantısı kuruyorum. Daha sonra sayfayı işler ve bu bağlantıya karşı tüm sorguları çalıştırırım. Bunu yapmanın en iyi yolu bu mu yoksa sorguyu her çalıştırdığımda veritabanı bağlantısı mı oluşturmalıyım?

ps 1 bağlantı oluşturmak ve kullanmak daha mantıklı geliyor, ancak bunun başka bir soruna neden olup olmadığını bilmiyorum.

MSSQL ile C # (ASP.NET) kullanıyorum.

Yanıtlar:


124

Her sorgu / işlem başına bir tane oluşturursanız, bağlantıları "kapatmayı" yönetmek çok kolaydır.

Neden sağduyu neden bir tane açıp onu kullanmanız gerektiğini belirlediğini anlayabiliyorum, ancak bağlantıların kopması ve okuyuculukla ilgili sorunlar yaşayacaksınız. Yani bir sonraki adımınız, bir havuz açmak, 50 demek, bağlantılar kurmak ve hepsini açık tutmak, farklı süreçlere sokmak olacak. Sonra bunun tam olarak .NET çerçevesinin sizin için ne yaptığını öğreneceksiniz .

İhtiyacınız olduğunda bir bağlantı açarsanız ve bittiğinde onu atarsanız, bu bağlantıyı gerçekten kapatmaz, tekrar kullanmak için bağlantı havuzuna geri gönderir.


Gönderdiğiniz zaman bu yazıyı okuyordum :) Teşekkürler.
webnoob

2
Bağlandığınız web sayfası SQL Server'a özeldir. .NET ayrıca diğer veritabanlarına bağlanırken otomatik havuz sağlar mı, örneğin, Oracle, Sqlite, MySql?
briddums

@briddums - Bunun konnektöre bağlı olduğunu düşünüyorum. Net, örneğin, bir MySQL konektörü sağlamaz. MySQL tarafından yazılmıştır. Ve işe yaramasına rağmen, benim deneyimime göre önceki uygulama hatasız olmaktan uzaktı.
ZweiBlumen

1
@briddums: Sağlayıcı montajına bağlıdır. Hem Microsoft’un hem de Oracle’ın kendi uygulamalarının bağlantı havuzunu desteklediğinden eminim, çünkü onları kullandım. Bunu yapan bir MySql olduğunu duydum ve Spring.NET'teki sağlayıcıların havuzlamayı desteklemesini beklerdim, ancak sağlayıcıya doğrudan arama yapmaktan veya doğrudan bana sormaktan daha iyisin.
pdr

1
Bir sorguyu açmak, çalıştırmak, bir bağlantıyı bir döngüde bile atmak, bir kez açıp sorguyu tekrarlamaktan daha hızlı ve bazen HIZLIDIR . Her zaman sadece elden çıkar. Daha güvenli ve HIZLI. Havuzdan bir bağlantı alma yükü hakkında endişelenmeyin - çok önemsiz.
smdrager

38

Sorgu başına bir bağlantı oluşturmak için en iyi yöntem - ve verilerin görüntülenmesi durumunda, en iyi uygulama, sorgunun gerekli tüm verileri tek seferde getirmesidir .

Arkaplan bilgisi:

.NET'te arama yapmak SqlConnection.Open()varsayılan olarak her zaman şeffaf bir şekilde havuz oluşturmayı kullanır ( MSDN'de "SQL Server ile Bağlantı Havuzlamasını Kullanma" konusuna bakın ). Böylece yeni bir bağlantı kurabilir Open()ve Close()işiniz bittiğinde arayabilir ve .NET doğru olanı yapacaktır.

Bağlantı havuzu oluşturmadan, sorgu başına bir bağlantının çok kötü bir fikir olacağını unutmayın, çünkü gerçek veritabanı bağlantıları oluşturmak çok maliyetli olabilir (kimlik doğrulama, ağ üzerinde genel gider vb.) Ve eşzamanlı açık bağlantıların sayısı genellikle çok sınırlıdır.


7
@webnoob - .NET, bağlantı havuzu oluşturduğundan, hayır, kullanmaz. Bunun nedeni, bağlantıların kapatılabileceği, yeniden tahsis edilebileceği vb. - bir bağlantının tekrar kullanılması iyi bir uygulama değildir .
Oded

11
-1 Cevap yanıltıcıdır. Sorgu başına bağlantı oluşturmak çok kötü bir fikirdir. Muhtemelen kastediyorsunuz "bağlantı havuzundan her sorgu için yeni bir bağlantı al" - ancak bu bir bağlantı oluşturmakla aynı değildir .
12'de sleske

1
@sleske - pdr'nin cevabından farkı nedir?
29.012'de

3
@Oded: Ah, anlıyorum. .NET'te, arama SqlConnection.Open()her zaman şeffaf bir şekilde havuz oluşturmayı kullanır. Bu nedenle, "bir bağlantı aç" ile "bir havuzdan bağlantı al" arasındaki fark yoktur. Benim yanlış anlama. Soruyla ilgili küçük bir açıklama düzenleme özgürlüğünü aldım ve oyu geri aldım.
sleske

2
@ eaglei22 - kesinlikle öyle yapmalı (bakınız docs.microsoft.com/en-us/dotnet/framework/data/adonet/… ). Genel olarak, en kısa sürede bağlantıyı havuza geri göndermek istersiniz; ancak, sırayla birkaç sorgu yayınlarsanız, bir bağlantıyı önerdiğiniz gibi yeniden kullanmak daha iyi olabilir . Hangi yaklaşımın sizin için daha iyi olduğunu test etmeniz ve görmeniz gerekir (hangi kriterleri kullandığınızı bilmiyorum - her iki yolu da kontrol edin ve seçtiğiniz metrikler üzerindeki etkisini görün).
Oded

0

Bütün bunların .Net ekosistemi bağlamında olduğunu unutmayın.

Geliştiriciler bazen bağlantı nesnelerini yeniden kullanmak için kodlarını "optimize etmek" ister. Bu sorunun bağlamı göz önüne alındığında, bu neredeyse her zaman bir hatadır.

ADO.Net, Bağlantı Havuzu Oluşturma adlı bir özelliğe sahiptir . Yeni bir bağlantı nesnesi oluşturup açtığınızda, gerçekte yaptığınız şey bir havuzdan bağlantı istemektir. Bir bağlantıyı kapattığınızda, onu havuza döndürürsünüz.

Bu, koda doğrudan kullanmak nesneleri anlamak önemlidir: SqlConnection, MySqlConnection, OleDbConnectio, vs, hepsi sadece vardır sarmalayıcıların ADO.Net tarafından yönetilen gerçek altta yatan bir bağlantı etrafında ve ADO.Net gerçek bağlantıları "ağır" çok ve daha pahalı performans açısından. Kimlik doğrulaması, ağa geçiş, şifreleme gibi endişeleri olan temel nesneler ve aslında kendi kodunuzda gördüğünüz nesnedeki küçük bellek miktarından daha ağır olan şeyler.

Bağlantı nesnesini yeniden kullanmaya çalıştığınızda, ADO.Net'in önemli altta yatan bağlantıları etkili bir şekilde yönetme özelliğini ortadan kaldırırsınız. Çok daha büyük bir şeyin pahasına küçük şeyde verimlilik elde edersiniz.

Bir uygulamayı veya http isteğinde bağlantıyı yeniden kullanmak, sizi paralel olarak çalışabilecek bir şeyi yanlışlıkla seri hale getirmeye ve performans darboğazı haline getirmeye zorlayabilir. Bunun gerçek uygulamalarda olduğunu gördüm.

Buradaki web sayfası örneğinde, en azından yalnızca tek bir http isteği / yanıtı süresi için küçük bağlantıyı sürdürdüğünüzde, istek hattınızda hangi sorguları çalıştırdığınızı değerlendirerek daha fazla verimlilik elde edebilir ve Bunları mümkün olduğu kadar az sayıda ayrı veri tabanına isteyin (ipucu: tek bir SQL dizesinde birden fazla sorgu gönderebilir ve aralarında hareket DataReader.NextResult()etmek için farklı tabloları kullanabilir veya kontrol DataSetedebilirsiniz).

Başka bir deyişle, bir uygulama için bir bağlantıyı veya sorgu başına bir bağlantıyı http isteği yeniden kullanma anlamındansa, veritabanına çağırdığınız her sefer için bir bağlantı anlamında düşünün ... her turda. Sonra bu yolculukların sayısını en aza indirerek bağlantı sayısını en aza indirmeye çalışın. Bu şekilde her iki hedefi de yerine getirebilirsiniz.


Ama bu sadece bir çeşit optimizasyon. Ayrıca programcı zamanını optimize etmek ve etkili kod yeniden kullanımı kazanmak da var. Geliştiriciler, yalnızca açık ve kullanıma hazır bir bağlantı nesnesi elde etmek için aynı kazan kodunu tekrar tekrar yazmak istemiyorlar. Sadece sıkıcı değil aynı zamanda hataları programa sokmanın bir yolu.

Burada bile olsa, genellikle sorgu başına (veya gidiş dönüş) bir bağlantı olması daha iyidir. Aynı kazan kodunu yeniden yazmamak için kullanabileceğiniz başka desenler de var. İşte sevdiğim bir örnek , ancak daha birçok var.


Ben bu partiye geç kaldım, ama bu cevap bazı önemli noktaları :) kapakları düşünüyorum
Joel Coehoorn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.