[C#] SqlDataAdapter 및 SqlDataReader

DB에서 데이터를 가져 오기 위해 SqlDataAdapter와 SqlDataReader를 사용하는 것의 차이점은 무엇입니까?

나는 그들의 장단점뿐만 아니라 속도와 메모리 성능을 구체적으로 살펴보고 있습니다.

감사



답변

SqlDataReader :

  • 끝날 때까지 연결을 유지합니다 (닫는 것을 잊지 마십시오!).
  • 일반적으로 한 번만 반복 할 수 있습니다
  • 데이터베이스로 다시 업데이트하는 데 유용하지 않습니다

반면에, 그것은 :

  • 전체 결과 세트가 아니라 한 번에 하나의 레코드 만 메모리에 있습니다 (이는 HUGE 일 수 있음 )
  • 한 번의 반복으로 얻을 수있는 속도만큼 빠릅니다.
  • 첫 번째 레코드를 사용할 수있게되면 결과 처리를 더 빨리 시작할 수 있습니다. 일부 쿼리 유형의 경우 매우 큰 문제 일 수 있습니다.

SqlDataAdapter / DataSet

  • 데이터로드가 완료되면 바로 연결을 닫을 수 있으며 자동으로 닫을 수도 있습니다
  • 모든 결과는 메모리에서 사용할 수 있습니다
  • 필요한 횟수만큼 반복하거나 색인별로 특정 레코드를 조회 할 수 있습니다.
  • 데이터베이스로 다시 업데이트하기위한 몇 가지 기본 기능이 있습니다.

비용 :

  • 훨씬 높은 메모리 사용
  • 데이터를 사용하기 전에 모든 데이터가로드 될 때까지 기다립니다

따라서 실제로는 수행중인 작업에 따라 다르지만 데이터 세트에서만 지원되는 것이 필요할 때까지 DataReader를 선호하는 경향이 있습니다. SqlDataReader는 읽기 전용 그리드에 바인딩하는 일반적인 데이터 액세스 사례에 적합합니다.

자세한 내용 은 공식 Microsoft 설명서를 참조하십시오 .


답변

그것에 대한 대답은 매우 광범위 할 수 있습니다.

기본적으로, 사용 결정에 영향을 미치는 주요 차이점은 SQLDataReader를 사용하면 데이터베이스에서 데이터를 “스트리밍”한다는 것입니다. SQLDataAdapter를 사용하면 데이터베이스에서 CRUD 조작을 수행 할뿐만 아니라 추가로 조회 할 수있는 오브젝트로 데이터를 추출합니다.

분명히 데이터 스트림을 사용하면 SQLDataReader가 훨씬 빠르지 만 한 번에 하나의 레코드 만 처리 할 수 ​​있습니다. SQLDataAdapter를 사용하면 데이터베이스에서 쿼리와 일치하는 행을 완전히 수집하여 코드를 처리 / 통과 할 수 있습니다.

경고 : SQLDataReader, ALWAYS, ALWAYS, ALWAYS를 사용하는 경우 SQLDataReader를 사용하여 연결을 열어두기 때문에 연결을 닫는 데 적합한 코드를 작성해야합니다. 이를 수행하지 않거나 결과 처리 오류가 발생하는 경우 연결을 닫는 적절한 오류 처리 는 연결 누수로 인해 응용 프로그램을 중단 시킵니다.

내 VB를 사면하지만 SqlDataReader를 사용할 때 필요한 최소 코드 양입니다.

Using cn As New SqlConnection("..."), _
      cmd As New SqlCommand("...", cn)

    cn.Open()
    Using rdr As SqlDataReader = cmd.ExecuteReader()
        While rdr.Read()
            ''# ...
        End While
    End Using
End Using     

동등한 C # :

using (var cn = new SqlConnection("..."))
using (var cmd = new SqlCommand("..."))
{
    cn.Open();
    using(var rdr = cmd.ExecuteReader())
    {
        while(rdr.Read())
        {
            //...
        }
    }
}


답변

SqlDataAdapter는 일반적으로 DataSet 또는 DataTable을 채우는 데 사용되므로 연결이 종료 된 후 (연결이 끊긴 액세스) 데이터에 액세스 할 수 있습니다.

SqlDataReader는 일반적으로 DataSet / DataTable을 채우는 것보다 빠른 경향이있는 빨리 감기 전용 및 연결된 커서입니다.

또한 SqlDataReader를 사용하면 한 번에 한 레코드 씩 데이터를 처리하고 메모리에 데이터를 보유하지 않습니다. 분명히 DataTable 또는 DataSet을 사용하면 메모리 할당 오버 헤드가 있습니다.

데이터를 메모리에 보관할 필요가 없으므로 렌더링 전용으로 SqlDataReader로 이동하십시오. 연결이 끊긴 방식으로 데이터를 처리하려면 DataAdapter를 선택하여 DataSet 또는 DataTable을 채우십시오.


답변

데이터베이스에서 메모리 내 DataSet / DataTable을 채우려면 SqlDataAdapter를 사용하십시오. 그런 다음 연결을 닫거나 처분하고 데이터 테이블 / 세트를 메모리에 전달할 수 있습니다. 그런 다음 InsertCommand / UpdateCommand와 함께 데이터 어댑터를 사용하여 데이터를 조작하고 DB에 다시 유지할 수 있습니다.

비즈니스 로직을 중심으로 데이터를 전달할 수있는 유연성 없이도 메모리가 적은 풋 프린트 데이터 액세스를 원할 경우 SqlDataReader를 사용하십시오. SqlDataAdapter 방식을 사용하면 모든 데이터를 한 번에 메모리에 모두로드하지 않기 때문에 대용량 데이터 볼륨의 빠른 메모리 부족 사용량 검색에 더 적합합니다. SqlDataAdapter 방식을 사용하면 DataSet / DataTable에 모든 데이터가 채워집니다. 많은 행과 열이 있으므로 많은 메모리가 필요합니다.


답변

Fill 함수는 내부적으로 DataReader를 사용합니다. “어느 쪽이 더 효율적인지”를 고려하면 레코드별로 컬렉션을 채우는 타이트 루프에서 DataReader를 사용하면 DataAdapter.Fill을 사용할 때와 동일한 시스템 부하가 발생할 수 있습니다.

(System.Data.dll, System.Data.Common.DbDataAdapter, FillInternal.)


답변