2011-09-12 1 views
0

이 질문에 실행하는 데 시간이 전혀 들지 않지만 마지막 줄의 주석 처리를 제거하는 데 5 초가 걸립니다. 어떻게 이것이 쿼리에 많은 영향을 미칠 수 있습니까? 거의 동일한 쿼리입니다.프리디 케이트 빌더를 사용하는 느린 쿼리의 문제점

return db.Parties.Where(predicate).Select(p => new SearchResult 
{ 
    adressPerson = p.Contacts.SingleOrDefault(m => m.contact_type == "H").streetname, 
    //adressOrg = p.Contacts.SingleOrDefault(m => m.contact_type == "W").streetname 
}); 

어떻게 문제를 찾을 수 있습니까? 나는 그것이 많은 코드를 게시 바보 그러나 여기 어쨌든 SQL 쿼리 알고

predicate = predicate.Or(p => p.surname.EndsWith(keyword)); 
    predicate = predicate.Or(p => p.lastname.EndsWith(keyword)); 
    predicate = predicate.Or(p => p.organisation.EndsWith(keyword)); 
    predicate = predicate.Or(p => p.Contacts.Any(c => c.streetname.EndsWith(keyword))); 
    predicate = predicate.Or(p => p.Memberships.Any(m => m.Congregation.congregation_name.EndsWith(keyword))); 
    predicate = predicate.Or(p => p.PartyCategories.Any(m => m.Category.category_name.EndsWith(keyword) || m.Category.category_code.EndsWith(keyword))); 

:

는 다음과 같은 술어가 모습입니다. 모든 단서?

SELECT (
    SELECT [t6].[streetname] 
    FROM [dbo].[Contact] AS [t6] 
    WHERE ([t6].[contact_type] = @p7) AND ([t6].[party_id] = [t0].[party_id]) 
    ) AS [adressPerson], (
    //SELECT [t7].[streetname] 
    //FROM [dbo].[Contact] AS [t7] 
    //WHERE ([t7].[contact_type] = @p8) AND ([t7].[party_id] = [t0].[party_id]) 
    //) AS [adressOrg] 
FROM [dbo].[Party] AS [t0] 
WHERE ([t0].[surname] LIKE @p0) OR ([t0].[lastname] LIKE @p1) OR ([t0].[organisation] LIKE @p2) OR (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [dbo].[Contact] AS [t1] 
    WHERE ([t1].[streetname] LIKE @p3) AND ([t1].[party_id] = [t0].[party_id]) 
    )) OR (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [dbo].[Membership] AS [t2] 
    LEFT OUTER JOIN [dbo].[Congregation] AS [t3] ON [t3].[congregation_id] = [t2].[congregation_id] 
    WHERE ([t3].[congregation_name] LIKE @p4) AND ([t2].[party_id] = [t0].[party_id]) 
    )) OR (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [dbo].[PartyCategories] AS [t4] 
    INNER JOIN [dbo].[Category] AS [t5] ON [t5].[category_id] = [t4].[category_id] 
    WHERE (([t5].[category_name] LIKE @p5) OR ([t5].[category_code] LIKE @p6)) AND ([t4].[party_id] = [t0].[party_id]) 
)) 

은 INNER 작동하지 않았다 마지막 선택 성명에서 가입 밝혀졌다 해결했다.

predicate = predicate.Or(p => p.PartyCategories 
    .GroupJoin(db.Categories, b => b.category_id, c => c.category_id, (b, c) => new { b, c }) 
    .SelectMany(c => c.c.DefaultIfEmpty(), (c, b) => new { c.c, b }) 
    .Any(m => m.b.category_name.EndsWith(keyword) || m.b.category_code.EndsWith(keyword))); 

답변

2

가 어떻게 문제를 찾아 않습니다 그래서 난에 술어의 마지막 줄을 변경?

항상 그렇듯이, 생성 된 SQL을보고 SQL 프로파일 러를 통해 실행하는 방법을 찾아야합니다.

제 생각에 단순한 내부 연결에서 하나의 접촉 유형에만 관심이 있거나 다소 복잡한 것으로, 또는 심지어 "N + 1-select"문제로 변경 될 것입니다. 어쨌든 SQL을 살펴보면 훨씬 명확 해집니다. 그 수준에서 무슨 일이 일어나고 있는지보고 제안

+0

나는이 방법으로 문제이었다고 생각한다. 술어를 다시 작성하면 SQL이 INNER JOIN 대신 LEFT OUTER JOIN이됩니다. – Niklas

+0

@Niklas : 맞습니다. 그리고 두 가지 경우에서 SQL 프로파일 러가 한 것을 보았습니까? –

+0

프로파일 러가없는 sqlexpress를 사용합니다 ... 제 생각 에는요? – Niklas

0

니클라스,

는 내가 SQL에 보일 것이다. 나는 또한이엔티티를 열심히로드하므로 초기 linq 쿼리에서 .Include()을 수행하는 것이 좋습니다. 그렇지 않으면 N + 1 선택 패턴에 게으른로드가됩니다. .included 사용을 위해 다음 링크를 체크 아웃 :

http://blogs.msdn.com/b/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx

Linq-to-entities - Include() method not loading

http://www.singingeels.com/Articles/Entity_Framework_and_Lazy_Loading.aspx

환호 ...

+0

EF를 사용하지 않습니다. Include()는 Linq에서 SQL로 작동합니까? – Niklas

+0

안녕하세요 niklas, 아 그때 아무도 어떤 차이를 만들 것입니다. .Include()는 단지 ef입니다. 그러나 큰 데이터 세트에서 인덱싱되지 않은 필드에 같은 명령문을 과도하게 사용하면 성능에 큰 영향을 미칠 수 있습니다. 어쨌든 고마워, –

+0

! 나중에 EF로 전환하면이 기능이 유용 할 것입니다. – Niklas