약 3 초 안에 11 개의 레코드를 반환해야하는 여러 조인이있는 L2S 쿼리가 있습니다. 그러나 Take 매개 변수를 지정하지 않으면 (11 레코드 만 반환하더라도 Take (20)을 사용함) 30 초 후에 시간이 초과됩니다.이 경우 11 개의 레코드로 3 초의 예상 시간 프레임에 반환됩니다.왜이 쿼리가 시간 초과됩니까?
쿼리는 다음과 같습니다
(from q in TransmittalDetails where q.TransmittalHeader.TransmittalEntityID == 196
&& q.TransmittalHeader.DateRangeBeginTimeID == 20100101
&& q.TransmittalHeader.ScenarioID == 2
&& q.LineItem.AccountType.AccountCategory.AccountGroup.
AccountSummary.AccountSummaryID == 6
select new {
q.LineItem.AccountType.AccountCategory.AccountGroup.AccountGroupID,
q.LineItem.AccountType.AccountCategory.AccountGroup.AccountGroup1
}).Distinct()
이이처럼 보이는 몇 가지 SQL을 생성합니다
DECLARE @p0 Int = 196
DECLARE @p1 Int = 20100101
DECLARE @p2 Int = 2
DECLARE @p3 Int = 6
SELECT DISTINCT [t5].[AccountGroupID], [t5].[AccountGroup] AS [AccountGroup1]
FROM [dbo].[TransmittalDetail] AS [t0]
INNER JOIN [dbo].[TransmittalHeader] AS [t1] ON [t1].[TransmittalHeaderID] =
[t0].[TransmittalHeaderID]
INNER JOIN [dbo].[LineItem] AS [t2] ON [t2].[LineItemID] = [t0].[LineItemID]
LEFT OUTER JOIN [dbo].[AccountType] AS [t3] ON [t3].[AccountTypeID] =
[t2].[AccountTypeID]
LEFT OUTER JOIN [dbo].[AccountCategory] AS [t4] ON [t4].[AccountCategoryID] =
[t3].[AccountCategoryID]
LEFT OUTER JOIN [dbo].[AccountGroup] AS [t5] ON [t5].[AccountGroupID] =
[t4].[AccountGroupID]
LEFT OUTER JOIN [dbo].[AccountSummary] AS [t6] ON [t6].[AccountSummaryID] =
[t5].[AccountSummaryID]
WHERE ([t1].[TransmittalEntityID] = @p0) AND ([t1].[DateRangeBeginTimeID] = @p1)
AND ([t1].[ScenarioID] = @p2) AND ([t6].[AccountSummaryID] = @p3)
이제, 정말 이상한 부분입니다 내가 실행하면 그 관리 Studio에서 SQL, 그것은 3 초에 11 개의 행을 반환하지만, 그것을 생성하는 linq 쿼리는 30 초 활동 후에 시간 초과됩니다.
Take 매개 변수를 지정하는 것은 의미가 없습니다. 내가 어떤 벌레를 치는거야?
참고 : 코드가 Take() 매개 변수없이 응용 프로그램 또는 Linqpad에서 실행되는지 여부에 관계없이 시간이 만료됩니다. 마찬가지로, app 및 linqpad에서 Take() 매개 변수를 사용하면 문제가 없습니다. 또한 별개 기호가 없으면 19 행만 반환합니다.
나는 이해가 확실하지 않다. L2S 쿼리에 의해 생성 된 SQL을 실행해도 아무런 문제가 없습니다. 생성 된 SQL의 실행 계획이 L2S 쿼리와 동일하지 않아야합니까? –
Linq-to-SQL 쿼리가 SQL로 변환됩니다. 시간이 초과되면 변환 된 특정 TSQL이 최적의 실행 계획보다 적게 실행 계획 캐시에 캐시됩니다. 관련된 테이블 중 하나에 sp_recompile 또는 dbcc freeproccache가 새로운 실행 계획을 강제합니다 ... – KristoferA
... 아, 프로파일 러를 사용하면 L2S가 데이터베이스를 치는 정확한 SQL 쿼리를 얻을 수 있습니다. 귀하의 질문에 "선언"진술로 시작하는 것은 L2S가 DB를 치는 것이 아닙니다. L2S는 sp_executesql을 사용하여 저장된 proc 계획 캐시에서 끝나기 위해 실행합니다. – KristoferA