복붙노트

[SQL] SqlCommand를 함께 사용할 때 왜 어떤 SQL 쿼리가 훨씬 느립니다?

SQL

SqlCommand를 함께 사용할 때 왜 어떤 SQL 쿼리가 훨씬 느립니다?

내가 저장 프로 시저가 훨씬 빠른 SQL Server 관리 Studio (2 분에서 시간)에는 System.Data.SqlClient.SqlCommand 실행 때보 (이초)에서 실행합니다.

그 이유 무엇을 할 수 있을까?

세부: SQL Server Management Studio를 (프로덕션 데이터베이스에서) 2 초이 실행에 :

EXEC sp_Stat
    @DepartmentID = NULL

에서 .NET / C # (프로덕션 데이터베이스에서) 2 분 밖에 다음 시간 :

string selectCommand = @"
EXEC sp_Stat
    @DepartmentID = NULL";
string connectionString = "server=***;database=***;user id=***;pwd=***";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    using (SqlCommand command = new SqlCommand(selectCommand, connection))
    {
        connection.Open();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
            }
        }
    }
}

또한 SelectCommand에 = "sp_Stat", CommandType을 =의 StoredProcedure, 그리고 SqlParameter에 함께 시도했지만 같은 결과입니다.

그리고 EXEC없이 잘 같은 결과입니다.

1 초 미만에서 거의 데이터 빈 개발 데이터베이스에 두 경우 모두 완료. 그것이 그와 관련된 그래서이 데이터베이스의 데이터를 많이하지만 단지 .NET에서 일어날 것 같다 ...

무엇 마크 Gravell 다른 설정 값에 대해 쓴 것은 제시 한 경우에 차이가 있습니다.

SQL Server 프로파일 러는 SQL Server Management Studio를 실행 것으로 나타났다 다음 SET의 .NET SQL 클라이언트 데이터 공급자하지 않는 것을 :


SET ROWCOUNT 0 
SET TEXTSIZE 2147483647 
SET NOCOUNT OFF 
SET CONCAT_NULL_YIELDS_NULL ON 
SET ARITHABORT ON 
SET LOCK_TIMEOUT -1 
SET QUERY_GOVERNOR_COST_LIMIT 0 
SET DEADLOCK_PRIORITY NORMAL 
SET TRANSACTION ISOLATION LEVEL READ COMMITTED 
SET ANSI_NULLS ON 
SET ANSI_NULL_DFLT_ON ON 
SET ANSI_PADDING ON 
SET ANSI_WARNINGS ON 
SET CURSOR_CLOSE_ON_COMMIT OFF 
SET IMPLICIT_TRANSACTIONS OFF 
SET QUOTED_IDENTIFIER ON
SET NOEXEC, PARSEONLY, FMTONLY OFF

나는이를 포함하는 경우, 동일한 쿼리는 SSMS와 .NET에서 같은 시간을했다. 그리고 책임 SET는 ...

SET ARITHABORT ON

나는 무엇을 배웠는가? 아마 추측의 프로파일 러를 대신 사용하는 ...

(처음에는이 솔루션은 매개 변수 스니핑과 관련이있을 것 같았다.하지만 몇 가지를 혼합했다 ...)

해결법

  1. ==============================

    1.중요 할 수있는 또 다른 일이 가능하게되어있는 SET 옵션입니다. 이러한 옵션 중 일부는 프로필을 변경하기 위해 충분히 쿼리 계획을 변경합니다. 옵션 설정이 호환되지 않는 경우가 강제 할 수있는 값을 다시 계산보다는 사용 : 일부는 지속 (및 인덱스) 열 계산 + (예를 들어)에서 찾고 있다면 큰 영향을 미칠 수 있습니다 인덱스 값 - 인덱스를 변경할 수있는 테이블 스캔 + 계산으로 구한다.

    중요 할 수있는 또 다른 일이 가능하게되어있는 SET 옵션입니다. 이러한 옵션 중 일부는 프로필을 변경하기 위해 충분히 쿼리 계획을 변경합니다. 옵션 설정이 호환되지 않는 경우가 강제 할 수있는 값을 다시 계산보다는 사용 : 일부는 지속 (및 인덱스) 열 계산 + (예를 들어)에서 찾고 있다면 큰 영향을 미칠 수 있습니다 인덱스 값 - 인덱스를 변경할 수있는 테이블 스캔 + 계산으로 구한다.

    SET 옵션은 "플레이"이 무엇인지 확인하기 위해 프로파일 러를 사용하여 시도하고 이러한 옵션을 사용하여 일을 변경하는 경우를 참조하십시오.

    또 다른 영향은 연결 문자열입니다; 예를 들어, 당신은 미묘한 방법으로 동작을 변경할 수 있습니다 MARS를 사용합니다.

    마지막으로, 트랜잭션 (암시 적 (TransactionScope에) 또는 명시 적)은 격리 수준에 따라 큰 영향을 미칠 수 있습니다.

  2. ==============================

    2.이 인해 '잘못된'캐시 된 쿼리 계획에 거의 확실하다. 이는 SO 꽤 몇 번에 올라와있다.

    이 인해 '잘못된'캐시 된 쿼리 계획에 거의 확실하다. 이는 SO 꽤 몇 번에 올라와있다.

    당신은 최신 통계가 있습니까? 정기적 인 스케줄 인덱스 유지 관리 계획?

    당신은 인해 저장 프로 시저 정의에이를 추가하여 캐시 된 쿼리 계획에 확실히 경우 테스트 할 수 있습니다 :

    CREATE PROCEDURE usp_MyProcedure WITH RECOMPILE...
    

    (데이터베이스가 매우 큰 경우주의!)이 전체 데이터베이스를 다시 인덱싱합니다 :

    exec sp_msforeachtable "dbcc dbreindex('?')"
    

    SO 게시물 :

    관리 Studio와 TableAdapter가 사이 저장된 프로 시저의 실행 시간에 큰 차이.

    SQL Server의 매개 변수 스니핑 (또는 스푸핑)

    SQL 서버 2005 알 수없는 최적화?

    같은 저장 프로 시저에 대한 다른 실행 계획

  3. ==============================

    3.비슷한 문제가 있었다 그것은 (최소한의 영향을 미칠 것으로 예상되는) 연결 문자열에 진정한 MultipleActiveResultSets을 = 가진 밝혀 원격 연결 걸릴을 통해 25분 대신 이분의 주위에 1.5mil의 기록을 당겨 만들고 있었다.

    비슷한 문제가 있었다 그것은 (최소한의 영향을 미칠 것으로 예상되는) 연결 문자열에 진정한 MultipleActiveResultSets을 = 가진 밝혀 원격 연결 걸릴을 통해 25분 대신 이분의 주위에 1.5mil의 기록을 당겨 만들고 있었다.

  4. ==============================

    4.우리는 쿼리 SSMS 2 초 만에 완료하고 .NET 클라이언트에서 호출 할 때 90 초 정도 걸릴 것입니다 비슷한 문제가 있었다 (우리가 그것을 테스트하기 위해 여러 VB / C 번호 애플리케이션 / 사이트를 썼다.)

    우리는 쿼리 SSMS 2 초 만에 완료하고 .NET 클라이언트에서 호출 할 때 90 초 정도 걸릴 것입니다 비슷한 문제가 있었다 (우리가 그것을 테스트하기 위해 여러 VB / C 번호 애플리케이션 / 사이트를 썼다.)

    우리는 쿼리 계획 힌트 (그리고 "인덱스" "에 가입 내부 루프") 다를 수 및 명시 적 루프와 쿼리를 재 작성 것이라고 의심. 이 문제를 해결했다.

  5. from https://stackoverflow.com/questions/801909/why-is-some-sql-query-much-slower-when-used-with-sqlcommand by cc-by-sa and MIT license