2012-04-11 4 views
1

더 나은 성능을 위해 조인없이 중첩 된 쿼리로 다음 쿼리를 다시 작성해야한다고 들었습니다. 사실입니까? 그렇다면 재 작성하는 방법은 무엇입니까?이것을 중첩 된 쿼리로 다시 작성하는 방법은 무엇입니까?

SELECT distinct A.Company_Name,C.Outlet_Name, 
     C.Outlet_FCE_ID,D.Usergroup_Name 
FROM company A, PURCHASE_INVOICE B, 
     Outlet C, User_Group D,CT_USER E 
WHERE A.Company_ID = B.Company_ID AND B.Outlet_ID = C.Outlet_ID 
    AND B.Company_ID = C.Company_ID AND B.Username = E.Username 
    AND E.Usergroup_ID=D.Usergroup_ID 

다음은 테이블 구조입니다.

enter image description here

+1

왜 중첩 된 쿼리는 일반적으로 조인보다 좋거나 나쁘지는 않습니까? 그것은 정말로 많은 것들에 달려 있습니다. 실제 문제는 너무 많은 데이터를 선택하고 'distinct'를 사용하여 중복을 제거한다는 사실과 관련 될 수 있습니다. 왜 '뚜렷한'것이 필요한가요? 외래 키에 관련된 모든 색인을 표시 할 수 있습니까? –

+2

나는 이것에 대해서도 궁금해. 필자의 경험에 따르면 인덱스가 올바르게 설정되었다고 가정하면 최적화 프로그램은 다른 것보다 조인을 최대한 활용할 것입니다. – moleboy

+0

천천히 실행되는 경우 실행 계획을 확인하거나 SQL 프로필러를 실행하십시오 (프로덕션 상자에 대해 사용하지 마십시오 :). 일단 파악한 후에는 열에 인덱스를 DBA에 추가하는 것이 좋습니다. 하지만 중첩 쿼리 성능에 대한 조인에 대한 다른 의견에 동의합니다. – Eugene

답변

0

:-)입니다. 나는 이런 식으로하지 않겠지 만 여기에 우리가 간다 ....

SELECT distinct 
     (SELECT Company_Name 
      FROM  dbo.COMPANY 
      WHERE  Company_ID = p.Company_ID 
     ) AS 'CompanyName' , 
     (SELECT Outlet_Name 
      FROM  dbo.OUTLET 
      WHERE  Company_ID = p.Company_ID 
        AND Outlet_ID = p.Outlet_ID 
     ) AS 'OutletName' , 
     (SELECT Outlet_FCE_ID 
      FROM  dbo.OUTLET 
      WHERE  Company_ID = p.Company_ID 
        AND Outlet_ID = p.Outlet_ID 
     ) 'OutletFCEID' , 
     (SELECT Usergroup_Name 
      FROM  dbo.USER_GROUP 
      WHERE  Usergroup_ID IN (SELECT Usergroup_ID 
             FROM  CT_USER 
             WHERE  Username = p.UserName) 
     ) 'UsergroupName' 
FROM dbo.PURCHASE_INVOICE p 
1

최적화 프로그램은이 권리를 얻어야한다, 그러나 당신은에 대해 원래 쿼리의 성능을 비교할 수도 있습니다 하나

select distinct 
    c.company_name, 
    o.outlet_name, 
    o.outlet_fce_id, 
    ug.usergroup_name 
from company c 
    inner join (select distinct company_id, outlet_id, username from purchase_invoice) i on c.company_id=i.company_id 
    inner join outlet o 
     on i.outlet_id = o.outlet_id 
     and i.company_id = o.company_id 
    inner join ot_user u  on b.username  = e.username 
    inner join user_group ug on u.usergroup_id = d.usergroup_id 

몇 가지 작업을 제거 할 수있는 purschases 테이블에 고유 한 ,하지만 그 많은 속임수가 있다면 나는 두 배로 늘린다.

purchase_invoice (username, outlet_id, company_id)에 대한 자세한 색인은 무엇입니까? 테이블에 covering index이 있으므로 속도가 빨라질 수 있습니다. 조인은 인덱스를 살펴 봐야만 실제 테이블을 읽지 않고 건너 뛸 수 있습니다. 테이블이 넓 으면 도움이됩니다.

또한 인덱스의 열 순서에 유의하십시오. ct_user도 많은 행을 가지고 있으며 Username에 클러스터 된 인덱스가 있다고 추측합니다. 이렇게하면 색인과 ct_user이 모두 사용자 이름에 따라 정렬되므로 두 개의 큰 표를 결합하는 데 merge join이 허용됩니다.

또한 user_group에 대해 c fr company 및 ug와 같은 테이블의 조인 구문과 의미있는 별칭을 사용하십시오. 그것은 데이터베이스에 중요하지 않지만 인간이 코드를 읽는 것을 막는 데 도움이됩니다. 또한, allcaps 당신의 비명 모든 시간처럼 보이지만 어쩌면 그것은 내 자신의 질문에 답할 수 있도록 그냥 날

GJ

관련 문제