2016-07-23 4 views
0

나는 이런 식으로 뭔가를 가지고 :왼쪽에 가입하거나 선택에서 선택 (SQL - 쿼리의 속도)

그것은 내가 3 개 선택하지 않고 내가 할 수 방법을 알고 싶어요, 선택 3가
SELECT CompanyId 
FROM Company 
WHERE CompanyId not in 
    (SELECT CompanyId 
    FROM Company 
    WHERE (IsPublic = 0) and CompanyId NOT IN 
     (SELECT ShoppingLike.WhichId 
      FROM Company 
      INNER JOIN 
      ShoppingLike ON Company.CompanyId = ShoppingLike.UserId 
      WHERE (ShoppingLike.IsWaiting = 0) AND 
       (ShoppingLike.ShoppingScoreTypeId = 2) AND 
       (ShoppingLike.UserId = 75) 
     ) 
    ) 

, 어느 하나는 100 만 건의 기록을위한 더 나은 속도가 있습니까? "select in select"또는 "left join"?

+0

성능이 문제가되면 하드웨어의 데이터베이스에서 데이터의 각 버전을 시험해보고 더 빠른 버전을 확인하십시오. –

+0

두 가지 질문이 있습니다. 왼쪽 조인을 준비 할 수 없습니다. 큰 데이터에 대해서는 테스트하지 못했습니다. ( – dan

+0

MS SQL이 사용자를 위해 수행한다면 옵티마이 저가 최적화 될 것이므로 걱정하지 마십시오. 귀하의 쿼리. companyId에 대한 인덱스를 만들면 MS SQL이 쿼리를 훨씬 빠르게 수행 할 수 있습니다. – Mahmoud

답변

0

내 경험은 오라클의 경험입니다. 까다로운 쿼리를 최적화하는 데 올바른 답은 결코 없으며, 이는 사용자와 옵티마이 저 사이의 공동 작업입니다. 당신은 종종 쿼리를 작성하는 각 단계에서 설명 계획과 때로는 흔적을 확인하여 옵티 마이저가 생각하는 바를 찾아야합니다. 그런 말로 미루어 보아 :

  • 당신은 그것의 전체 내용을 바꾸어 외부 SELECT을 제거 할 수있는 것은 NOT( ... )에서 하위 쿼리 WHERE 절입니다. 그것의 얼굴에 회사의 외부 전체 스캔 (또는 그것은 회사 색인의 인덱스)을 방지합니다. 시도해보십시오. 출력이 동일한 지 확인하고 타이밍을 얻은 다음 아래에서 시도하기 전에 일시적으로 제거하십시오. NOT()은 암시 적 OR이 작성되어 Optimizer가 ShoppingLike 부속 조회에 대한 ANTI-JOIN을 고려하지 않게합니다.
  • CompanyId 및 WhichId가 NOT NULL 열로 정의되어 있는지 확인하십시오. 이것 (또는 명시 적으로 CompanyId IS NOT NULL 등)이 없으면 ANTI-JOIN 옵션은 종종 버려집니다.
  • 내부 대부분의 하위 쿼리는 상관 관계가 없으므로 (외부 쿼리의 내용을 참조하지 않으므로) 별도로 추출하고 조정할 수 있습니다. 작풍의 사정으로 나는 그것에 대하여 모든 여과기가 있기 때문에 당신이 ShoppingLike를 첫째로 검사하고 싶은대로 INNER JOIN의 주위에 테이블 이름을 교환 할 것입니다. 차이는 없지만 읽기 쉽고 힌트를 사용하여 지정된 순서대로 테이블을 스캔 할 수 있습니다. 이 하위 쿼리에서 Company 테이블의 필요성에 대해서도 의문을 제기 할 것입니다.
  • NOT IN을 사용했을 때 매우 비슷한 NOT EXISTS이 옵티 마이저에 더 많은/대체 옵션을 제공하는 경우가 있습니다.

설명 계획을 시도하기 전에는 위의 모든 내용이 시행 착오 일뿐입니다. 오라클은 다음 바람으로 LEFT JOININSELECT 사이로 변환 할 수 있습니다. 1M + 행은 투자 시간을 창출합니다.

+0

감사합니다. – dan