SELECT TOP 1은 쿼리 성능을 저하시킵니다. 이것을 극복 할 수있는 dba 액세스 가능한 방법이 있습니까?


13

프로덕션 응용 프로그램 (C #에서 SQL Server 2014 Standard와 통신)에는 아래와 같은 쿼리가 있습니다. 대부분 밀리 초 단위로 실행됩니다. 그러나 때때로 (의 특정 값에 대해 @Id), 견딜 수 있고 1 분 정도 걸립니다. 앱 시간이 초과되어 사용자가 앱을 사용할 수 없습니다.

"goes nuts"경우, 반환 된 결과 세트는 다른 경우가 많지 않지만 대부분 비어 있으므로 올바르게 비어 있습니다.

운 좋게도 프로덕션 환경과 개발 환경 모두에서 재현 할 수 있습니다.

개발자는 쿼리에서 "TOP 1"을 제거한 다음 앱이 결과 집합의 추가 행을 소비하도록하여 성능 문제를 해결한다고 말합니다.

쿼리 플래너는 인덱스가 없을 때 인덱스를 제안하지 않습니다 TOP 1. (개발자).

쿼리 변경 및 앱 수정이 진행 중입니다. 롤아웃에는 시간이 걸립니다.

내 질문 : 새로운 쿼리가 출시 될 때까지 응용 프로그램이 변경되기 전에 프로덕션 SQL Server 인스턴스를 조정하거나 조정 하여이 문제를 극복 할 수있는 DBA 액세스 가능한 방법이 있습니까?

SELECT TOP 1
       subscription_id 
  FROM subscription AS sub
  JOIN billing_info AS bi ON bi.billing_info_id = sub.billing_info_id   
  JOIN person_group AS apg ON apg.person_id = bi.person_id
  JOIN pplan ON pplan.plan_id = sub.plan_id
  JOIN product ON product.product_id = [plan].product_id 
  JOIN product_attribute ON product_attribute.product_id = product.product_id 
 WHERE apg.group_id = @Id
   AND apg.start_date < GETDATE()
   AND (apg.end_date IS NULL OR apg.end_date > GETDATE()) 
   AND (sub.end_date IS NULL OR sub.end_date > GETDATE()) 
   AND product_attribute.attribute_type = 'special feature' 
   AND product_attribute.attribute_data = '1' 
 ORDER BY sub.start_date ASC;

하위 쿼리로 사용해 보셨습니까? 예를 들어 다음에서 1 개의 subscription_id를 선택하십시오 ([
top1이

어쩌면 "정상적인"쿼리 튜닝이 작동합니까? 인덱스가 충분히 매력적이면 스캔이 사라집니다. 그것은 계획 지침보다 덜 침습적입니다.
usr

그래서 같은 값이 @ID 항상 "고약"이됩니까? 그렇다면 해당 값 중 하나를 사용하여 테스트하고 실제 쿼리 계획을 캡처하십시오. 무엇이 잘못되었는지 알려줄 것입니다. "나쁜"값이 일치하지 않으면 이것이 매개 변수 스니핑 (솔루션에 대한 @MartinSmith의 답변 참조)이거나 클라이언트가 실제로 결과 세트를 요청하고 소비하는 방법과 관련된 잠금 문제 일 가능성이 높습니다.
RBarryYoung

답변:


12

쿼리를 변경할 수없는 경우 계획 지침을 사용할 수 있습니다.

를 사용하여 쿼리 성능을 테스트하십시오 OPTION (QUERYTRACEON 4138)(이 작업을 수행 할 sysadmin권한이있는 사람이 필요함 ).

이것이 만족스러운 성능을 제공하는 경우 계획 지침과 함께 적용 할 수 있습니다. 만족스러운 성능을 얻지 못하면 힌트를 찾아보십시오. OPTION (HASH JOIN, MERGE JOIN)부적절한 중첩 루프가 문제인 경우 가능 합니다. USE PLAN N'...'힌트 에 의지해야 할 수도 있습니다 .

필요한 힌트를 알고 나면 여기 정보를 사용하여 힌트를 적용 할 수 있습니다 .


OPTION (QUERYTRACEON 4138)트릭을했다. 감사. 이제 계획 가이드를 정렬합니다.
O. Jones

0

grins에 대해서는 이것을 시도하십시오
`>는> =로 변경되므로 정확히 동일한 쿼리는 아닙니다.

SELECT TOP 1
       subscription_id 
  FROM subscription AS sub
  JOIN billing_info AS bi 
        ON bi.billing_info_id = sub.billing_info_id   
  JOIN person_group AS apg 
        ON apg.person_id = bi.person_id 
       AND apg.group_id = @Id
       AND apg.start_date < GETDATE()
       AND isnnull(apg.end_date, GETDATE()) >= GETDATE()             
  JOIN pplan 
        ON pplan.plan_id = sub.plan_id
       AND isnnull(sub.end_date, GETDATE()) >= GETDATE()
  JOIN product 
        ON product.product_id = [plan].product_id 
  JOIN product_attribute 
        ON product_attribute.product_id = product.product_id 
       AND product_attribute.attribute_type = 'special feature' 
       AND product_attribute.attribute_data = '1' 
 ORDER BY sub.start_date ASC;

"쿼리 변경 및 앱 수정이 진행 중입니다. 롤아웃에는 시간이 걸립니다." OP는 성능을 "있는 그대로"수정하는 솔루션을 찾고 있습니다.
Martin Smith

@MartinSmith 그리고 그들이 픽스를 출시 할 때 더 나은 픽스가 될 수 있습니다. 앱이 추가 행을 소비하게 만드는 것은 다른 프로그램 변경 사항입니다.
paparazzo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.