2010-06-24 1 views
0

섹션 중간의 쿼리에서 IN 키워드를 사용하고 있습니다. 중첩 쿼리를 사용하고 있고 InExists으로 바꾸려면 노인이 저에게 말한 성능 문제로 인해 문제가 발생할 수 있습니다.IN을 EXISTS 또는 COUNT로 바꿉니다. 그것을하는 방법. 여기서 누락 된 것은 무엇입니까?

일부 쿼리가 누락되었습니다.이 쿼리에서 무엇을 찾고 있습니까? 이 쿼리에는 읽기 쉽도록 일부 별칭이 포함되어 있습니다.

어떻게 제거 할 수 있습니까?

SELECT TX.PK_MAP_ID AS MAP_ID 
     , MG.PK_GUEST_ID AS Guest_Id 
     , MG.FIRST_NAME 
     , H.PK_CATEGORY_ID AS Preference_Id 
     , H.DESCRIPTION AS Preference_Name 
     , H.FK_CATEGORY_ID AS Parent_Id 
     , H.IMMEDIATE_PARENT AS Parent_Name 
     , H.Department_ID 
     , H.Department_Name 
     , H.ID_PATH, H.DESC_PATH 
FROM   
    dbo.M_GUEST AS MG 
     LEFT OUTER JOIN 
    dbo.TX_MAP_GUEST_PREFERENCE AS TX 
      ON 
       (MG.PK_GUEST_ID = TX.FK_GUEST_ID) 
     LEFT OUTER JOIN 
    dbo.GetHierarchy_Table AS H 
      ON 
       (TX.FK_CATEGORY_ID = H.PK_CATEGORY_ID) 
WHERE  
    (MG.IS_ACTIVE = 1) 
     AND 
    (TX.IS_ACTIVE = 1) 
     AND 
    (H.Department_ID IN -----How to remove this IN operator with EXISTS or Count() 
       ( 
       SELECT C.PK_CATEGORY_ID AS DepartmentId 
       FROM 
        dbo.TX_MAP_DEPARTMENT_OPERATOR AS D 
         INNER JOIN 
        dbo.M_OPERATOR AS M 
          ON 
           (D.FK_OPERATOR_ID = M.PK_OPERATOR_ID) 
            AND 
           (D.IS_ACTIVE = M.IS_ACTIVE) 
         INNER JOIN 
        dbo.L_USER_ROLE AS R 
          ON 
           (M.FK_ROLE_ID = R.PK_ROLE_ID) 
            AND 
           (M.IS_ACTIVE = R.IS_ACTIVE) 
         INNER JOIN 
        dbo.L_CATEGORY_TYPE AS C 
          ON 
           (D.FK_DEPARTMENT_ID = C.PK_CATEGORY_ID) 
            AND 
           (D.IS_ACTIVE = C.IS_ACTIVE) 
       WHERE  
        (D.IS_ACTIVE = 1) 
         AND 
        (M.IS_ACTIVE = 1) 
         AND 
        (R.IS_ACTIVE = 1) 
         AND 
        (C.IS_ACTIVE = 1) 
      )--END INNER QUERY 
    )--END Condition 

IN을 EXISTS 또는 COUNT로 바꾸면 어떤 새로운 문제가 발생할 수 있습니까? 기본적으로

답변

4

, 난 당신이 내가이 대체 할 수있는 방법을 묻는 질문 이해 :

where exists (select...) 

나이 :

where (select count(*) from ...) > 1 

그것이이와

where H.department_id in (select departmentid from...) 

을 매우 간단합니다. 한 가지 방법은 다음과 같습니다.

WHERE... 
    AND EXISTS (select c.pk_category_id 
       from tx_map_department_operator d 
       inner join m_operator as m 
        on d.fk_operator_id = m.pk_operator_id 
       inner join l_user_role l 
        on m.fk_role_id = r.pk_role_id 
       inner join l_category_type c 
        on d.fk_department_id = c.pk_category_id 
       where h.department_id = c.pk_category_id 
       and d.is_active = 1 
       and m.is_active = 1 
       and r.is_active = 1 
       and c.is_active = 1 
      ) 

여분의 조인 때문에 is_active에서 여분의 조인을 제거했습니다. 인덱스로 실행하는 방법을 테스트해야합니다. 인덱스가 더 빠를 수도 있기 때문입니다. 나는 그것을 의심한다. 내가 그 존재 알고 있기 때문에 그러나, 조인 절 (join on ... and x.is_active=y.is_active)를 추가하거나 where 절 (x.is_active=1 and y.is_active=1 and z.is_active=1...)

에 확인하고 난 당신이 단지 count(*) 대신, exists를 사용하는 것이 좋습니다 것 빠른 여부를 비교하는 가치가있다 1 행을 찾은 후에 멈추어야합니다. 반면 count는 완료 될 때까지 계속 실행 된 다음 참조 값 (개수> 1)과 비교됩니다.

제쳐두고, 이상한 컬럼 명명 표준입니다. 기본 키에는 PK 프리픽스가 있고 외래 키에는 FK 프리픽스가 있습니까? 나는 그것을 본 적이 없다.

+0

그래, 나는 명명 표준이 성가신다고 생각했다. 그들은 확실히 쿼리를 덜 읽을 수있게합니다. – SiN

+0

SIN : 명명 규칙이 약간 터무니 없다는 것에 동의하지만, PM도 TL도 아닌 SE도 변경 될 수 있으므로, 우리에게 들려오는 내용을 따라야합니다. 여기 내 질문은 H.Department 제거의 영향입니다. 내가 여기서 생각하는 것은 어떻게 그것이 같은 결과를 얻는가하는 것이다. –

+0

나는 그것이 H 테이블에 합류해야한다고 생각한다. 위에서 변경 한 사항. 그러나 지금 나는 그 의도를 잘 모르겠다. 내부 쿼리에서 H 테이블을 사용하면 속도가 크게 느려질 수 있습니다. – MJB

관련 문제