2009-11-09 3 views
6

Linq에서 SQL에 큰 성능 문제가 있음을 발견했습니다.Linq to SQL nvarchar 문제

문자열을 사용하여 테이블에서 선택하면 sql 테이블이 varchar 인 경우에도 sql 서버에 전달되는 매개 변수는 항상 nvarchar입니다. 이로 인해 검색이 아닌 테이블 스캔이 발생하여 성능 문제가 심각합니다.

var q = (
    from a in tbl 
    where a.index == "TEST" 
    select a) 

var qa = q.ToArray(); 

파라미터

전체 인덱스 초래 사용되기 전에 NVARCHAR하는 VARCHAR 변환되는 NVARCHAR로 통과한다.

매개 변수가 varchar 인 경우 매우 빠르게 탐색됩니다.

재정의하거나 변경할 수있는 방법이 있습니까?

감사합니다. 감사합니다. 크레이그.

+0

DBML의 모습은 어떻습니까? – RobS

+0

이것은 varchar 열이며 nvarchar 열은 아닙니다. create table test (test varchar (200) not null) 테스트에서 인덱스 ixtest 생성 (테스트) – Craig

+0

데이터베이스 쿼리 계획은 seek 대신 CONVERT_IMPLICIT 및 스캔을 사용합니다. SQL 문제에 대한 일반적인 LINQ라고 생각합니다. 매개 변수를 올바르게 지정할 수있는 해결 방법을 찾고 있습니다. varchar (200) 대신 nvarchar (4)로 변환됩니다. – Craig

답변

8

흠. 이것은 RTM 이전의 LINQ-to-SQL 빌드가있는 알려진 버그 였지만, 온라인에서 읽은 것에서 이것은 RTM의 평등 비교에 대한 고정 된 문제였습니다 (Contains() 비교를 위해 여전히 손상되었지만). http://social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/4276ecd2-31ff-4cd0-82ea-7a22ce25308b

내가 가장 좋아하는 해결 방법은 이것이다 :

//define a query 
IQueryable<Employee> emps = from emp in dc2.Employees where emp.NationalIDNumber == "abc" select emp; 

//get hold of the SQL command translation of the query... 
System.Data.Common.DbCommand command = dc2.GetCommand(emps); 

//change param type from "string" (nvarchar) to "ansistring" (varchar) 
command.Parameters[0].DbType = DbType.AnsiString; 
command.Connection = dc2.Connection; 

//run 
IEnumerable<Employee> emps2 = dc2.Translate<Employee>(command.ExecuteReader()); 

BTW, 내가 본 다른 경우에 이런 일이 있었다

에 관계없이, 여기에 몇 가지 해결 방법이 설명과 MSDN 포럼에 스레드입니다 테이블의 50 %에 같은 값이있는 경우) 계획 컴파일시 SQL Server에 매개 변수가 알려지지 않았기 때문에 테이블 스캔이 사용 가능한 최상의 계획이었습니다. 배포본이 비정상적인 경우 위의 해결 방법은 누락 된 변환이 아니라 매개 변수화 자체에서 오는 스캔이므로 작동하지 않습니다. 이 경우 OPTIMIZE FOR 힌트를 사용하고 SQL을 수동으로 지정하는 것이 유일한 해결책입니다.

+0

+1 .. :) 다른 대체 해결 방법이있는 또 다른 msdn 스레드가 있습니다. http://social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/20d456f0-9174-4745-bbc5-571f68879e27 – KristoferA

+0

감사합니다. 내가 포함 된 것으로 만 문제가 있다는 것을 깨달았습니다. 나는 그것이 처음에는 더 광범위하다고 생각했다. – Craig