2017-11-16 7 views
0

I가 다음과 같은 데이터베이스 테이블SQL 선택 하위 쿼리

User   List 
------  ------ 
userId (PK) listId (PK) 
fullName  description 
       addedById (FK with userId in User table) 
       modifiedById (FK with userId in User table) 

나는 목록 테이블에서 모든 데이터를 꺼내해야하지만 대신 의 ID를 보여주는의이 modifiedById을 addedById, I fullName사용자 테이블에서 가져와야합니다.

이 쿼리가 작동하고 필요한 데이터를 제공합니다. 그러나이 쿼리를 구성하는 더 좋은 방법이 있는지 확실하지 않습니다. 주로 성능 문제로 인해 주요 선택 쿼리 내에서 여러 하위 선택 쿼리를 사용하는 것이 중요하지 않습니다.

select t1.[description], 
    t1.addedById, 
    t1.modifiedById, 
    (select fullName from dbo.User where userId = t1.addedById) as [AddedByUser], 
    (select fullName from dbo.User where userId = t1.modifiedById) as [ModifiedByUser] 

from dbo.List t1 

누군가가 쿼리 개선을 제안하거나 그대로 유지하도록 부탁드립니다.

감사합니다.

+2

LEFT JOIN이 대신합니다. – jarlh

+3

'userId'에 대한 색인이 있다고 가정하면 조회가 잘됩니다. 또 다른 접근법은 LEFT JOIN입니다. 두 접근법 모두 성능이 비슷해야합니다. –

+1

SO에 대한 주제 외. CodeReview에 게시하는 것이 좋습니다. –

답변

1

보다 표준 SQL 방법은 다음과 같습니다

SELECT t1.description, 
    t1.addedById, 
    t1.modifiedById, 
    add.fullName AS [AddedByUser], 
    mod.fullName AS [ModifiedByUser] 
FROM dbo.List t1 
LEFT JOIN dbo.User add 
    ON add.userId = t1.addedById 
LEFT JOIN dbo.User mod 
    ON mod.userID = t1.modifiedById 

그러나, 나는이 쿼리에 동일하게 수행하고 아마도 동일한 실행 계획을 가지고 것입니다 생각한다. 이 방법의 유일한 장점은 확장하는 것이 더 쉽다는 것입니다. 예를 들어 사용자 테이블에서 새 열을 추가하려는 경우이 방법이 더 쉽습니다.

@Gordon은 조인하려는 필드에 인덱스가 있으면 성능이 좋을 것이라고 말합니다.

+0

이 대체 방법은 매우 유용합니다. 내가 참여하고있는 분야에 대한 색인이 있으며 두 가지 접근 방식 모두에서 어떤 차이점도 발견하지 못했습니다. – tgriffiths

1

동일한 테이블로 두 번 가입하면 방해가됩니까? 그것은 느린 것이 아니며 링크 된 하위 쿼리를 만드는 대신 선호하는 방법입니다.

나는 PK와 두 FK에서 모두 색인을 가지고 있다고 가정하고 있습니다.

최소화 할 수있는 것은 결합 된 행의 수를 줄이는 것입니다. 왼쪽 내부 조인을 사용하거나 where 절을 사용하여 필터링을 수행 할 수 있습니다. join에서 사용하는 두 키가 null이 아니어야 함을 나타냅니다.

두 예제를 모두 작성할 수 있지만 설명은 자명해야합니다.

사용자가 할 수있는 다른 시장은 값을 PRESELECT하는 것입니다. 예를 들어 사용자가 많고 두 가지 역할을 수행 할 수있는 사용자는 거의 없습니다. 또한 목록에없는 사용자의 일부 열을 기준으로 어떤 열을 필터링 할 수 있으며 해당 열에 인덱스가있는 경우 더 효율적입니다.

그런 다음 해당 사용자 만 사전 선택하고 선택 결과에 참여하면 도움이 될 수 있습니다. 둘 다 사전 선택 될 수있는 경우 임시 테이블을 사용하거나 대신 전체 테이블에 조인하여 지점을 선택합니다. 관련성이 있기 위해 여기에서 다루고있는 번호에 대해서는 확실하지 않습니다.