2010-01-21 2 views
5

나는 종종 자신이 다음과 같이 SQL 쿼리를 작성하고자 찾을 :SQL :이 같은 쿼리는 OK입니까, 아니면 조인 사용과 같은 효율적인 방법입니까?

SELECT body 
    FROM node_revisions 
where vid = (SELECT vid 
       FROM node 
       WHERE nid = 4); 

나는 조인과 당신이 할 수있는 물건이 있다는 것을 알고 있지만, 그들은 일을 더 복잡하게 만들 것으로 보인다. 조인은 더 좋은 방법인가? 더 효율적입니까? 더 쉽게 이해할 수 있을까요?

+1

SQL Server에서 쿼리와 논리적으로 동등한 조인이 동일한 쿼리 실행 계획을 가지고 있기 때문에 기꺼이 할 수 있습니다. – Dana

답변

7

이 데이터베이스를 염두에두고 설정 작업 작성되기 때문에보다 효율적 경향이 조인 (및 운영을 설정 조인) : 동일하고 모든 것을, 왜 함께하지.

그러나 성능은 데이터베이스에 따라 달라지며 테이블의 구조, 데이터의 양 및 쿼리에서 반환되는 값이 달라집니다.

데이터 양이 적 으면 조인이 아닌 사용자의 하위 쿼리를 사용합니다. 그것이 실패 할 것 nid = 4, 더 이상의 노드 레코드의 기회가 나는, 당신은 게시 된 쿼리를 사용하지 않을

SELECT body 
FROM node_revisions nr 
INNER JOIN node n 
    ON nr.vid = n.vid 
WHERE n.nid = 4 

: 여기

은의 모습에 가입하는 것이다.

내가 사용합니다 :

SELECT body 
FROM node_revisions 
WHERE vid IN (SELECT vid 
      FROM node 
      WHERE nid = 4); 

이 더 읽기 또는 이해할 수 있습니까? 이 경우 개인의 취향이 중요합니다.

+0

그것은 개인적인 취향 이상입니다. 가독성을 비교하는 IN을 사용하여 두 개의 열에 대한 조인을보고 싶습니다. 솔직히, IN을 과용하는 것은 SQL의 핵심 개념 문제의 증상 일 수 있습니다. – ErikE

1
select 
    body 
from node_revisions A 
where exists (select 'x' 
       from Node B 
       Where A.Vid = B.Vid and B.NID=4) 
+2

왜 더 좋은가요? 그것은 더 복잡해 보입니다. –

+0

더 복잡하지만 같은 일을하지 않습니다. 이것은 semi-join으로, 어떤 경우 데이터베이스 서버가 최적화를 수행하도록 허용합니다. 또한 하위 쿼리 테이블에 일치하는 행이 몇 개 있는지에 관계없이 항상 주 테이블에서 한 행만 반환합니다. 기본 쿼리에서 하위 쿼리의 열을 참조 할 수는 없지만 중요한 것은 데이터를 가져 오지 않고 * 존재 *를 확인하는 것입니다.또한 외부 테이블의 행 당 행 수가 많은 행이 하위 쿼리 테이블에있는 경우 존재 구문은 한 개만 찾은 후 중지 할 수 있으므로 훨씬 효율적입니다. – ErikE

+0

이것은 원래 쿼리와 논리적으로 동일하지 않습니다. 여러 행을 반환하는 하위 쿼리의 경우이 작업이 수행되고 원래 쿼리가 실패합니다. 이것은'= '대신'IN'을 사용하는 쿼리와 동일합니다. 그러나 모든 현대 엔진은'EXISTS'와'IN'을 모두 semi-join으로 최적화 할 수 있습니다. – Quassnoi

3

데이터베이스의 모든 성능 관련 질문에 대한 대답은 따라 이며, 우리는 OP의 세부 사항에 대한 짧은입니다. 상황에 대한 구체적인 내용을 알고하지 ...

조인 어떤 이유로 여러 열 키가 필요한 경우 더 쉽게이

  • 을 이해하기 위해 (비린내)된다 (따라서,이 엄지 손가락의 일반적인 규칙은) , 조인을 계속 사용하고 다른 표현식을 조인 조건에 간단히 집어 넣을 수 있습니다.
  • 나중에 보조 데이터를 조인 할 필요가 있으면 조인 프레임 워크가 이미 있습니다.
  • 당신이 가입하고있는 곳과 색인을 구현해야하는 위치를 정확하게 알 수 있습니다.
  • 조인을 사용하면 조인을 더 잘 수행 할 수 있으며 조인에 대해 더 잘 생각할 수 있습니다.

서면 질의 effiency와 *

쿼리 작성하고 무엇을 실제로 실행됩니다 서로 거의 상관이를 아무 상관이없는 플레이에 어떤 테이블에 대한 명확

  • 조인. 쿼리 작성 방법은 여러 가지가 있지만 데이터를 가져 오는 방법은 매우 드뭅니다. 쿼리 엔진에 따라 결정됩니다. 이것은 주로 색인과 관련이 있습니다. 전혀 다른 것처럼 보이지만 내부적으로는 똑같은 네 가지 쿼리를 작성할 수 있습니다.

    (* 그것은 비효율적이다 끔찍한 쿼리를 작성하는 것이 가능하지만, 그렇게. 미친 특별한 종류의 소요)

    select 
        body 
    
    from node_revisions nr 
    
    join node n 
    on n.vid = nr.vid 
    
    where n.nid = 4 
    
  • 1

    자동으로 표현하는 변환합니다 최신 MySQL의 6.x의 코드 실제로 할 아주 간단 그것을 밖으로 쓰기,

    http://forge.mysql.com/worklog/task.php?id=3740

    을하지만 : 내부는 반 조인 하위 쿼리 최적화를 사용하여 주로 해당하는 2 문을 가입 INNER JOIN이 기본 조인 유형이기 때문에이를 수행하는 서버에 의존하지 않을 것입니다 (어떤 이유에서든 그렇지 않든간에 반드시 결정할 수있는).

    select body from node_revisions r, node n where r.vid = n.vid and n.node = 4 
    
    3

    조인은 이해하기 쉽고 더 효율적일 수 있다고 생각합니다. 귀하의 사례는 매우 간단하므로 아마 toss-up 일 것입니다.

    SELECT body 
        FROM node_revisions 
        inner join node 
         on (node_revisions.vid = node.vid) 
        WHERE node.nid = 4 
    
    1

    나는 당신이 쓴 것과 아무 잘못 표시되지 않습니다, 그리고는 적합한 경우에 좋은 최적화도 조인으로 변경 될 수 있습니다 : 여기에 내가 그것을 쓰는 것이 방법이다.

    1
    SELECT body 
    FROM node_revisions 
    WHERE vid = 
         (
         SELECT vid 
         FROM node 
         WHERE nid = 4 
         ) 
    

    이 쿼리는이 nidPRIMARY KEY이거나 UNIQUE 제약 조건이 적용되는 경우에만 가입에 논리적으로 동일합니다.

    그렇지 않으면 쿼리가 동일하지 않습니다. 더 이상 1 행이 node이고 nid = 4 인 경우 하위 쿼리는 실패하지만 항상 조인은 성공합니다.

    nidPRIMARY KEY 인 경우 JOIN과 하위 쿼리는 동일한 성능을가집니다. 경우

    node가 부질 경우

    선두로한다 조인 부질 한번 실행되고 분석 단계에서 const로 변환한다.

    select body 
    from node_revisions nr 
    join node n on nr.vid = n.vid 
    where n.vid = 4 
    

    그러나 당신은 또한이 가입없이 가입 표현할 수있다 : A는 가입

    +0

    넵, nid 및 vid는 고유 기본 키입니다. –

    +0

    '@Brian T. Hannan' : 그러면 쿼리가 동일합니다. 'JOIN'과 서브 쿼리는 같은 기능을 수행합니다. – Quassnoi

    2

    은 재미있다 [!] :

    select body 
    from node_revisions nr, node n 
    where n.nid = 4 and nr.vid = n.vid 
    

    흥미롭게도, SQL 서버 모두에 약간의 다른 쿼리 계획을 제공합니다 쿼리는 클러스터 된 인덱스 스캔이있는 반면 "조인하지 않고 조인"은 그 위치에 클러스터 된 인덱스 찾기가 있습니다. 이는 적어도이 경우 better임을 나타냅니다.