2017-11-29 7 views
3

Azure SQL 데이터베이스를 사용할 때 EntityFramework에 의해 생성 된 매개 변수화 된 쿼리를 사용할 때 성능 차이를 알게되었습니다.Azure SQL의 매개 변수화 된 쿼리 성능 저하 NVARCHAR (4000)

기본 키가있는 테이블이 있는데 기본 키를 사용하여 해당 테이블에서 값을 가져 오려고하면 EntityFramework는 NVARCHAR (4000)을 데이터 형식으로 사용하여 매개 변수화 된 쿼리를 만듭니다.

DECLARE @p__linq__0 nvarchar(4000) 
SET @p__linq__0 ='ehenurqp0kpql76kjsw3' 

select * from mediacontentreferences where [email protected]__linq__0 

이렇게하면 Azure SQL 데이터베이스에서 매우 이상한 실행 계획이 생성됩니다. 그것은 전체 테이블을 통해 보이는 인덱스 스캔을 사용하기 때문에

Azure SQL execution plan 1

그것은 매우 비효율적이다.

올바른 데이터 형식의 매개 변수를 사용하는 경우 실행 계획은 기본 키 인덱스를 사용합니다.

Azure SQL execution plan 2

내가 온 - 프레미스 SQL 서버의 첫 번째 쿼리를 사용하는 경우

DECLARE @p__linq__1 varchar(30) 
SET @p__linq__1 ='ehenurqp0kpql76kjsw3' 

select * from mediacontentreferences where [email protected]__linq__1 

은, 실행 계획은 VARCHAR (30)에 NVARCHAR (4000) 변환 및 기본 키 인덱스를 사용합니다. SQL Server execution plan 1

이는 푸른 SQL 서버의 실행 계획 계산의 결함 것 같습니다.

Entity Framework에서 쿼리를 만드는 방식이 바뀔 수 있습니까?

몇 가지 기사를 읽었지만 해결 방법은 없습니다. 생성 쿼리는 올바른 데이터 유형 매개 변수를 선언합니다 동안

Why does code first/EF use 'nvarchar(4000)' for strings in the raw SQL command?

Why does Entity Framework generate large parameters? How can they be reduced?

+0

사내 구축 형 시스템의 SQL Server 버전은 무엇입니까? –

+0

열에 대해 hasmaxlength 설정을 사용 하시겠습니까? https://prashantbrall.wordpress.com/2011/04/ –

+0

온 - 프레미스, 2008 R2와 2014를 모두 테스트했으며, 둘 다 작동합니다. – Dan

답변

2

당신은 EF보다, 당신의 열의에 적합한 데이터 유형을 지정해야합니다.

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<mediacontentreferences >().Property(e => e.mediacontentreferenceid).HasColumnType("varchar"); 
    } 
+0

예, EntityFramework (thx)에 의해 생성 된 실제 쿼리를 수정하지만, Azure SQL Server가 제공된 쿼리에서 해당 "creative"실행 계획을 사용하는 이유에 대해서는 대답하지 않습니다. – Dan

+0

@ Dan, 이것은 Azure와는 아무런 관련이 없습니다. 문제는 varchar 데이터 형식으로 열을 정의하지만 쿼리에서 nvarchar를 사용하여 매개 변수를 선언 할 경우 SQL Server는 형식 변환을 수행해야하며 인덱스를 사용할 수 없습니다. –

+0

그러나 왜 다른 SQL 서버 버전이 다른 계획을 가지고 있습니까? 데이터 유형이 일치하지 않고 Azure에서 실행하는 경우에만 색인 스캔을 제안합니까? – Dan