저는 Linq2SQL을 사용하여 "급증한"프로젝트를 가지고 있으며 이제 주요 쿼리 성능 문제가 발생합니다. 그림을 이동.SQLServer 쿼리 최적화 질문
Linq 실제로 간단한 쿼리 및 명령 시나리오에서 꽤 잘 작동하지만 Sprocs로 다시 작성해야하는 몇 가지 필터 강렬한 쿼리가 있습니다.
누군가 Linq에 의해 생성 된 괴물 쿼리를 최적화하는 데 시간을 절약 할 수있는 상위 수준 포인터를 줄 수 있는지 궁금합니다.
내 머리 꼭대기에서, "In (@ p1, @ p2)"대체는 내부 조인을 사용하는 where 절이 좋은 시작이라고 생각합니다.
모든 외래 키 및 where 절 열에 대한 색인이 생성됩니다.
모든 의견에 감사드립니다.
여기 코드 : 당신이 추측 할 수 있었다 모르기 때문에
SELECT [t9].[ID], [t9].[Description], [t9].[AreaCodeID], [t9].[BedroomCodeID], [t9].[BathroomCodeID], [t9].[DwellingCodeID], [t9].[LandlordID], [t9].[ParsedItemID], [t9].[DeletedReasonID], [t9].[CoordinateID], [t9].[Address], [t9].[PhonePrefix1], [t9].[Phone1], [t9].[PhonePrefix2], [t9].[Phone2], [t9].[EmailAddress], [t9].[RentAmount], [t9].[SquareFeet], [t9].[DateAvailable], [t9].[DateCreated], [t9].[IsDeleted], [t9].[RowVersion], [t9].[ID2], [t9].[ParentAreaCodeID], [t9].[AreaGroupID], [t9].[Description2], [t9].[Order], [t9].[IsTopLevelArea], [t9].[IsDeleted2], [t9].[ID3], [t9].[CityID], [t9].[Description3], [t9].[Order2], [t9].[IsPrimary], [t9].[IsDeleted3], [t9].[ID4], [t9].[HostURL], [t9].[Description4], [t9].[Rate], [t9].[RateTax], [t9].[RateTaxCode], [t9].[Currency], [t9].[LogoImageFileName], [t9].[FlashQuotesFileName], [t9].[TestimonialQuotesFileName], [t9].[GoogleAnalyticsTrackingCode], [t9].[GoogleMapsAPIKey], [t9].[IDHash], [t9].[test], [t9].[ID5], [t9].[Description5], [t9].[ID6], [t9].[Description6], [t9].[Order3], [t9].[IsDeleted4], [t9].[ID7], [t9].[Description7], [t9].[IsDeleted5], [t9].[Order4]
FROM (
SELECT TOP (100) [t0].[ID], [t0].[Description], [t0].[AreaCodeID], [t0].[BedroomCodeID], [t0].[BathroomCodeID], [t0].[DwellingCodeID], [t0].[LandlordID], [t0].[ParsedItemID], [t0].[DeletedReasonID], [t0].[CoordinateID], [t0].[Address], [t0].[PhonePrefix1], [t0].[Phone1], [t0].[PhonePrefix2], [t0].[Phone2], [t0].[EmailAddress], [t0].[RentAmount], [t0].[SquareFeet], [t0].[DateAvailable], [t0].[DateCreated], [t0].[IsDeleted], [t0].[RowVersion], [t1].[ID] AS [ID2], [t1].[ParentAreaCodeID], [t1].[AreaGroupID], [t1].[Description] AS [Description2], [t1].[Order], [t1].[IsTopLevelArea], [t1].[IsDeleted] AS [IsDeleted2], [t2].[ID] AS [ID3], [t2].[CityID], [t2].[Description] AS [Description3], [t2].[Order] AS [Order2], [t2].[IsPrimary], [t2].[IsDeleted] AS [IsDeleted3], [t3].[ID] AS [ID4], [t3].[HostURL], [t3].[Description] AS [Description4], [t3].[Rate], [t3].[RateTax], [t3].[RateTaxCode], [t3].[Currency], [t3].[LogoImageFileName], [t3].[FlashQuotesFileName], [t3].[TestimonialQuotesFileName], [t3].[GoogleAnalyticsTrackingCode], [t3].[GoogleMapsAPIKey], [t3].[IDHash], [t5].[test], [t5].[ID] AS [ID5], [t5].[Description] AS [Description5], [t6].[ID] AS [ID6], [t6].[Description] AS [Description6], [t6].[Order] AS [Order3], [t6].[IsDeleted] AS [IsDeleted4], [t7].[ID] AS [ID7], [t7].[Description] AS [Description7], [t7].[IsDeleted] AS [IsDeleted5], [t7].[Order] AS [Order4]
FROM [dbo].[Listing] AS [t0]
INNER JOIN ([dbo].[AreaCode] AS [t1]
INNER JOIN ([dbo].[AreaGroup] AS [t2]
INNER JOIN [dbo].[City] AS [t3] ON [t3].[ID] = [t2].[CityID]) ON [t2].[ID] = [t1].[AreaGroupID]) ON [t1].[ID] = [t0].[AreaCodeID]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t4].[ID], [t4].[Description]
FROM [dbo].[BathroomCode] AS [t4]
) AS [t5] ON [t5].[ID] = [t0].[BathroomCodeID]
INNER JOIN [dbo].[BedroomCode] AS [t6] ON [t6].[ID] = [t0].[BedroomCodeID]
INNER JOIN [dbo].[DwellingCode] AS [t7] ON [t7].[ID] = [t0].[DwellingCodeID]
WHERE (NOT ([t0].[IsDeleted] = 1)) AND (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[ListingMiscellaneousCode] AS [t8]
WHERE ([t8].[MiscellaneousCodeID] IN (@p0, @p1, @p2, @p3, @p4, @p5, @p6)) AND ([t8].[ListingID] = [t0].[ID])
)) AND ([t0].[DwellingCodeID] IN (@p7)) AND ([t0].[AreaCodeID] IN (@p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22, @p23, @p24, @p25, @p26, @p27, @p28, @p29, @p30, @p31, @p32, @p33, @p34, @p35, @p36, @p37, @p38, @p39, @p40, @p41, @p42, @p43, @p44, @p45, @p46, @p47, @p48, @p49, @p50, @p51, @p52, @p53, @p54, @p55, @p56, @p57, @p58, @p59, @p60, @p61, @p62, @p63, @p64, @p65, @p66, @p67, @p68, @p69, @p70, @p71, @p72, @p73, @p74, @p75, @p76, @p77, @p78, @p79, @p80, @p81, @p82, @p83, @p84, @p85, @p86, @p87, @p88, @p89, @p90, @p91, @p92, @p93, @p94, @p95, @p96, @p97, @p98, @p99, @p100, @p101, @p102, @p103, @p104, @p105, @p106, @p107, @p108, @p109, @p110, @p111))
) AS [t9]
ORDER BY [t9].[DateCreated] DESC, [t9].[RentAmount], [t9].[Description2]
, 문제의 부분은 완전히 Where 절에 있습니다. 이 결과를 제거하면 쿼리가 매우 빠르게 진행됩니다.
이 Where 절을 사용하더라도 느리지 만 (약 1 초) 문제는 아니지만 비슷한 스타일 쿼리를 기반으로 현재 데이터를 여러 번 반환해야하는 문제가 있습니다. 가난한 Where 절이있는 다중 쿼리로 인해 전체 프로세스가 5 초를 초과합니다.
내가 이해하지 못하는 또 다른 사실은 쿼리의 페이지 크기를 "TOP (100) 선택 ..."과 같이 높은 숫자로 변경하는 것입니다 ... "TOP (5000) ... "는 쿼리를 AT 전체에서 느려지지 않습니다. 이것은 나에게 이상한 일이며, 문제가 수정 된 SQL으로 고칠 수 있다고 생각하는 많은 증거입니다.
또한 특정 Where 절 (areacodeid)이 거의 100 개의 매개 변수를 쿼리하고 있음을 알 수 있습니다. 이는 의도적으로 설계된 동작입니다. 이제는 부모 테이블에서 해킹을하여 일부 비정규 화를 희생시키면서이를 줄이기 위해 사용할 수 있습니다.하지만 먼저 100 자의 params가있는 임시 테이블에 효율적으로 참여할 수있는 순수한 SQL 수정이 필요합니다. .
도움 주셔서 감사합니다.
원본 Linq 쿼리 (또는 쿼리)와 함께 기본 스키마 (테이블 및 인덱스)를 포함 시키면 수정 될 수 있습니다. 특이한 것이 없기 때문에 성능에 문제가있는 경우 저장된 procs에 의지하지 않고 수정할 수 있습니다. – KristoferA
... 아, 그리고 추가하는 걸 잊었습니다 ... 쿼리가 충분히 잘 수행되지 않으면 _find_ 먼저 성능 문제의 원인을 찾으십시오. 그런 다음 최적화하십시오. 시각 장애인에게 최적화하는 것은 시간 낭비입니다. 동일하게 도움이되는 쿼리에 대한 실행 계획 및 I/O 통계 [링크]를 포함 할 수있는 경우 – KristoferA