2011-11-16 2 views
2

SQL Server 데이터베이스가 있고 ADO.NET ExecuteReader를 사용하여 데이터 배열을 가져 왔습니다. 내 스토어드 프로 시저는 약 35,000 개의 레코드를 반환합니다. 정말 이상한 DataReader 성능 문제

이가 ExecuteReader를 호출하면 DataReader가를 반환하는 약 3 초하고있다.

나는이 항목과 비슷한 코드를 사용하고 있습니다.

using(var conn = new SqlConnection(MySQLHelper.ConnectionString)) { 
    conn.Open(); 
    var sqlCommand = SqlHelper.CreateCommand(conn, "spGetItems"); 
    using (var dr = sqlCommand.ExecuteReader()) { 
     while(dr.read){ 
      var item = new Item{ID = dr.GetInt32(0), ItemName = dr.GetString(1)}; 
      items.Add(item); 
     } 
    } 
} 

(가) 읽기의 대부분은 0 밀리 초를하고있다. 그러나, 간헐적으로 약 5.5 초 (5000 + 밀리 초) 소요되는 읽기 있어요. 나는 데이터를 보았고 평범함을 찾을 수 없었다. 나는 오랫동안 복용했던 기록의 빈도를 살펴보기 시작했다.

재미있었습니다. 완전히 일치하지는 않지만 그들은 가깝습니다. 다음과 같이 하였다로드하는 데 시간이 오래 복용 하였다 기록 ...

기록 #S : 29, 26,26,27,27,29,302827273030,26, (26) (30)에 기록이 몇 밀리 초에 0에서 읽을 것이며, 다음 5 초, 예상대로 그 다음 26 ~ 30 레코드를 다시 읽을 것입니다 걸릴 것 같은 27

그래서 그것은 본다.

나는 완전히 손실되었습니다. 더 많은 코드를 게시 할 수 있지만 그다지 많은 코드는 없습니다. 그것은 아주 간단한 코드입니다.

EDIT 아니요, 내 필드에 varchar (최대) 또는 그 이상인 사람이 없습니다. 나의 가장 큰 분야는 숫자 (28,12)입니다.

저장 프로 시저를 수정 한 후에 더 이상 문제가 없습니다. 먼저 Top 100을 선택하도록 수정 한 다음 Top 1000으로, 그 다음 10,000으로, 그리고 나서 100,000으로 올렸습니다. 나는 그것들에 결코 문제가 없었다. 그런 다음 TOP로 이동했는데 이전에는 문제가 없었습니다. 클라이언트로 전송

+0

100 개 항목 만 반환하도록 저장 프로 시저를 수정하면 정상적으로 실행됩니다. 나는이 양을 늘려 성능이 크게 떨어지는 숫자가 있는지 알아볼 것입니다. –

답변

3

SqlDataReader 버퍼 결과. this page on MSDN for details 참조 :

결과가 클라이언트로 전송됩니다

는, SQL 서버가 클라이언트에 전송 된 패킷의 수를 최소화, 각 패킷에 많은 결과 집합 행이 할 수있는 넣습니다.

패킷 당 26-30 개의 레코드가있는 것으로 의심됩니다. 레코드를 반복하면서 새로운 레코드가로드 될 때까지 지연이 발생합니다.

+0

그건 의미가 있습니다. –

+0

가능합니다. 그러나 왜 30hz 기록을 검색하는 데 5 초가 걸릴까요? –

+0

@ jdv-JandeVaan 아무리 생각해도 - 잠재력이 매우 큰 네트워크 연결이 아니면 서버의 스트레스 등이 있습니다 ... –

0

읽고있는 테이블의 구조는 무엇입니까? 두 번째 열에 nvarchar (최대) 형식을 사용하지 마십시오?

+0

최대 열이 없습니다. 모두 길이 150 이하로 제한됩니다. –

0

프로그램없이 저장 프로 시저를 실행하는 데 시간이 얼마나 걸립니까? 나는 그 시간이 오래 걸릴 것으로 예상하고, 다른 사람들이 지적했듯이, 당신은 버퍼링 때문에 이상한 행동을보고있다.

+0

저장 프로 시저의 실행 시간은 0.25 ~ 2 초입니다. –

1

나는 비슷한 문제가있었습니다. 대답은 nvarchar (max)를 사용하여 모든 텍스트 필드를 캐스팅 한 다음 .NET ExecuteReader를 비슷한 기간 내에 MS Studio의 sproc Exec에 반환했습니다. sproc에는 트랜잭션이 포함되어 있지 않지만 .NET 호출은 트랜잭션으로 래핑되었습니다.