데이터베이스 연결 작성-한 번 또는 각 쿼리마다 수행됩니까?


101

현재 웹 페이지가 처음로드 될 때 데이터베이스 연결을 만듭니다. 그런 다음 페이지를 처리하고 해당 연결에 대해 모든 쿼리를 실행합니다. 이것이 최선의 방법입니까, 아니면 쿼리를 실행할 때마다 데이터베이스 연결을 만들어야합니까?

추신 : 하나의 연결을 만들어서 사용하는 것이 더 합리적이지만 이것이 다른 문제를 일으킬 수 있는지 모르겠습니다.

MSSQL과 함께 C # (ASP.NET)을 사용하고 있습니다.

답변:


124

쿼리 / 트랜잭션 당 하나를 만들면 연결 "닫기"를 관리하는 것이 훨씬 쉽습니다.

상식에 따라 열어서 사용해야한다는 이유를 알 수 있지만 연결 끊기와 멀티 스레딩에 문제가 발생할 수 있습니다. 따라서 다음 단계는 풀을 열고 (예 : 50 개) 연결을 모두 열어 두어 다른 프로세스에 할당하는 것입니다. 그리고 이것이 .NET 프레임 워크가 이미 당신을 위해하는 것임을 알게 될 것 입니다.

필요할 때 연결을 열고 처리가 끝났을 때 처리하면 연결이 실제로 닫히지 않고 연결 풀로 돌아가서 다시 사용할 수 있습니다.


당신이 그것을 게시했을 때 그 기사를 읽고있었습니다 :) 감사합니다.
webnoob

2
연결 한 웹 페이지는 SQL Server에만 해당됩니다. .NET은 다른 데이터베이스 (예 : Oracle, Sqlite, MySql)에 연결할 때 자동 풀링을 제공합니까?
briddums

@ briddums-커넥터에 따라 다릅니다. 예를 들어 .Net은 MySql 커넥터를 제공하지 않습니다. MySql이 작성하고 유지 관리합니다. 그리고 그것이 작동하는 동안 내 경험상 초기 구현에는 버그가 없었습니다.
ZweiBlumen

1
@briddums : 공급자 어셈블리에 따라 다릅니다. Microsoft의 Oracle 구현과 Oracle 자체가 모두 연결 풀링을 지원한다고 확신합니다. 나는 MySql이 있다고 들었습니다 .Spring.NET의 공급자가 풀링을 지원할 것으로 기대하지만 나에게 묻는 것보다 공급자를 직접 검색하거나 요청하는 것이 좋습니다.
pdr

1
루프에서도 쿼리를 열고, 실행하고, 연결을 배치하는 것이 한 번만 열고 쿼리를 반복하는 것보다 빠르며 때로는 더 빠릅니다 . 항상 폐기하십시오. 더 안전하고 빠릅니다. 풀에서 연결을 가져 오는 오버 헤드에 대해 걱정하지 마십시오. 너무 간단합니다.
smdrager

38

쿼리마다 하나의 연결을 만드는 것이 가장 좋습니다. 데이터를 표시하는 경우 필요한 모든 데이터를 한 번에 가져 오는 것이 좋습니다 .

배경 정보:

.NET에서 호출 SqlConnection.Open()은 기본적으로 항상 연결 풀링을 투명하게 사용 합니다 ( MSDN의 "SQL Server에서 연결 풀링 사용" 참조 ). 따라서을 사용하여 새 연결을 가져 와서 완료되면 Open()호출 Close()하면 .NET이 올바른 작업을 수행합니다.

연결 풀링이 없으면 실제 데이터베이스 연결을 만드는 데 비용이 많이 들며 (인증, 네트워크 오버 헤드 등) 일반적으로 동시 연결 수는 매우 제한적이기 때문에 쿼리 당 하나의 연결은 매우 나쁜 생각입니다.


7
@webnoob-.NET은 연결 풀링을 사용하기 때문에 그렇지 않습니다. 연결이 닫히고 재 할당 될 수 있으므로 연결을 재사용하는 것은 좋지 않습니다 .
Oded

11
-1 대답은 다소 오해의 소지가 있습니다. 쿼리 당 연결을 만드는 것은 매우 나쁜 생각입니다. 아마도 "연결 풀에서 각 쿼리에 대해 새 연결을 검색"하는 것이지만 연결 을 만드는 것과는 다릅니다 .
sleske

1
@ sleske-pdr의 답변과 다른 점은 무엇입니까?
Oded

3
@Oded : 아, 알겠습니다. .NET에서 호출 SqlConnection.Open()은 항상 연결 풀링을 투명하게 사용합니다. 따라서 "연결 열기"와 "풀에서 연결 검색"의 차이점은 없습니다. 내 오해 나는 질문에 대한 약간의 설명을 자유롭게 편집하고 투표권을 되찾았다.
sleske

2
@ eaglei22-반드시 그렇게해야합니다 ( docs.microsoft.com/en-us/dotnet/framework/data/adonet/… 참조 ). 일반적으로, 당신은 당신이 순서대로 쿼리 수를 발행하는 경우,하지만, 가능한 한 빨리 풀에 연결을 반환 할 것입니다 수있는 당신이 제안으로 연결을 다시 사용하는 것이 더합니다. 어떤 접근 방식이 더 나은지 테스트하고 확인해야합니다 (어떤 기준을 사용하는지 모르겠습니다. 두 가지 방법을 모두 확인하고 선택한 측정 항목에 미치는 영향을 확인하십시오).
Oded

0

이 모든 것이 .Net 생태계의 맥락에 있음을 기억하십시오.

개발자는 때때로 연결 객체를 재사용하기 위해 코드를 "최적화"하기를 원합니다. 이 질문의 맥락에서 볼 때 이것은 거의 항상 실수입니다.

ADO.Net에는 연결 풀링 이라는 기능이 있습니다. 새 연결 개체를 만들고 열 때 실제로 수행하는 작업은 풀에서 연결을 요청하는 것입니다. 연결을 닫으면 풀로 돌아갑니다.

코드에서 직접 사용하는 개체를 이해하는 것이 중요합니다. SqlConnection, MySqlConnection, OleDbConnectio 등은 모두 ADO.Net에서 관리하는 실제 기본 연결을 래퍼 로 묶고 ADO.Net 실제 연결은 훨씬 "무겁고"더 비쌉니다. 성능 관점에서. 인증, 네트워크 전송, 암호화와 같은 문제가있는 기본 개체이며 실제 코드에서 실제로 볼 수있는 개체의 메모리 양보다 훨씬 큽니다.

연결 개체를 재사용하려고하면 ADO.Net이 중요한 기본 연결을 효과적으로 관리 할 수 ​​없게됩니다. 훨씬 더 큰 것을 희생시키면서 작은 것에서 효율성을 얻습니다.

응용 프로그램 또는 http 요청에서 연결을 다시 사용하면 실수로 병렬로 실행될 수있는 것을 직렬화하여 성능 병목 현상이 발생할 수 있습니다. 실제 응용 프로그램에서 발생하는 것을 보았습니다.

적어도 하나의 http 요청 / 응답 기간 동안 최소한의 연결 만 유지하는 웹 페이지 예의 경우 요청 파이프 라인에서 실행하는 쿼리를 평가하여 더 많은 효율성을 얻을 수 있습니다. 가능한 한 데이터베이스에 대한 별도의 요청이 적습니다 (단일 : 단일 SQL 문자열로 둘 이상의 쿼리를 제출하고 DataReader.NextResult()서로 다른 테이블을 사용 하거나 확인 DataSet하여 이들 사이를 이동할 수 있습니다).

다시 말해, 응용 프로그램 또는 http 요청에 대해 하나의 연결을 다시 사용하는 것과 쿼리 당 하나의 연결을 다시 사용한다는 점을 고려하기보다는 데이터베이스를 호출 할 때마다 매 라운드마다 하나의 연결을 고려하십시오. 그런 다음 트립 수를 최소화하여 연결 수를 최소화하십시오. 이런 식으로 두 목표를 모두 만족시킬 수 있습니다.


그러나 그것은 한 종류의 최적화 일뿐입니다. 또한 프로그래머 시간을 최적화하고 효과적인 코드 재사용을 얻고 있습니다. 개발자는 열려 있고 바로 사용할 수있는 연결 개체를 얻기 위해 동일한 상용구 코드를 반복해서 작성하고 싶지 않습니다. 지루할뿐만 아니라 프로그램에 버그를 도입하는 방법이기도합니다.

그럼에도 불구하고 일반적으로 쿼리 (또는 왕복) 당 하나의 연결을 갖는 것이 좋습니다. 동일한 상용구 코드를 다시 쓰지 않도록하기 위해 사용할 수있는 다른 패턴이 있습니다. 여기 제가 좋아하는 한 가지 예가 있지만 다른 것들도 많이 있습니다.


나는이 파티에 늦었지만이 답변이 몇 가지 중요한 사항을 다루고 있다고 생각합니다. :)
Joel Coehoorn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.