2016-10-18 5 views
0

,이 기록되었습니다는, SQL의 조건과 속도를 결합

SELECT * 
FROM ta A 
JOIN tb B 
    ON A.col1 = B.col1 
JOIN tc C 
    ON B.col2 = C.col2 
WHERE B.col3 = 'whatever' 
AND C.col4 = 'whatever2' 

을 그리고 난 다음에 대해 생각하기 시작했다 :

SELECT * 
FROM ta A 
JOIN (SELECT * FROM tb WHERE col3 = 'whatever') B 
    ON A.col1 = B.col1 
JOIN (SELECT * FROM tc WHERE col4 = 'whatever2') C 
    ON B.col2 = C.col2 

(I 틀리지 않는 경우 , 결과는 동일합니다). 나는 그것이 훨씬 더 빨라지는지 궁금하다. 내 생각 엔 그럴 것입니다. 그러나 왜/왜 안되는지 알고 싶습니다.

는 (우리 서버가 순간에 아래이기 때문에, 나는 그래서 내가 여기 부탁 해요, 지금 그것을 나 자신을 테스트 할 수 없습니다, 당신이 마음을하지 바랍니다.)

가 (여기서 중요한, 엔진 Vertica,하지만 내 질문은 정말 Vertica에 특정되지 않습니다)

+0

동일합니까? 시도 해봐. 어느 것이 더 빠릅니까? 시도 해봐. 로컬 테스트 서버를 사용하십시오. 넌 없어? 그것을 설정하십시오. –

+0

"오라클"에 대해 같은 질문을하는 것을 기억하고 설명 계획을 확인할 때도 비슷했습니다. 당신은 당신의 DB를 위해 똑같이 시도 할 수 있습니다. – Utsav

+0

귀하의 질문 *은 * 쿼리 * 최적화 방법에 따라 달라 지므로 * 특정 * Vertica 있습니다. 이러한 성능을 처리하는 일반적인 방법은 인덱스, 파티셔닝 및 알고리즘 선택입니다. 일반적으로 우리는 합리적인 결정을 내리기 위해 최적화 프로그램을 사용합니다. –

답변

1

두 번째 쿼리가 있어야한다, 조금 꺼져 :

SELECT * 
FROM ta A 
JOIN (SELECT * FROM tb WHERE tb.col3 = 'whatever') B 
    ON A.col1 = B.col1 
JOIN (SELECT * FROM tc WHERE tc.col4 = 'whatever2') C 
    ON B.col2 = C.col2 

공지 사항 절을보기 위해, 범위에 포함되지 별칭을 테이블을 참조 할 필요가 인라인보기. B와 C는 인라인보기에서 범위를 벗어납니다.

어떤 경우에도 내부 조인을 수행 중이므로 사전 조인 또는 사후 조인 중 어떤 조건이 발생하든 상관 없으므로 결과 관점에서 중요하지 않습니다.

당신은 합리적으로 다음을 수행 최적화에 의존 할 수

  1. 만 필요할 때 필요한 열을 실현.이 두 문장 사이에 차이점이 없습니다 말했다

의미을 만드는 곳

  • 푸시 다운 술어. 대부분의 경우 첫 번째 술어에 대한 술어를 두 번째 것과 유사하게 만들기 위해 술어를 밀고 있습니다. 수집 된 통계가있는 경우 옵티마이 저는 똑같은 방식으로 (또는 실제로 닫는) 쿼리 할만큼 똑똑해야합니다.

    두 번째 쿼리에서 Vertica에서 두 번째 쿼리 수정 문제를 보지 못했지만 ... 일반적으로 복수 COUNT(DISTINCT ...) 식 또는 theta 조인 등을 사용할 때만 나타납니다.

    이제는 외부 조인이면 명령문이 달라집니다. 첫 번째 필터는 조인 후에 필터를 적용하고 두 번째 필터는 조인 전에 필터를 적용합니다.

    물론 두 가지 방법에 대한 설명 만하면됩니다. 통계가 수집되었는지 확인하십시오.

    희망이 있습니다.

  • 0


    안녕,
    아주 좋은 시도하십시오. 정말 감사합니다. 첫 번째 쿼리는 제대로 작동하지만 두 번째 쿼리는 실행되지 않고 오류가 발생합니다. 그 이유는 다음과 같습니다. JOIN (SELECT * FROM tb WHERE B.col3 = '무엇이든') B on A.col1 = B.col1. 이 조건에서 열을 으로 일치시킵니다. A.col1 = B.col1. 여기에 ta 테이블에서 A.col1이 표시되지만 B.col1이 표시되지 않습니다. 조인에서 하위 쿼리를 지정하는 동안 '*' 연산자를 사용하지 않아야합니다. 조인은 하위 쿼리에서이 연산자를 인식하지 못합니다. 필수 열 이름을 지정해야합니다. 아래 쿼리의 예와 같이

    SELECT * 
    FROM ta A 
    JOIN (SELECT col1,col2 FROM tb WHERE B.col3 = 'whatever') B 
        ON A.col1 = B.col1 
    JOIN (SELECT col2 FROM tc WHERE C.col4 = 'whatever2') C 
        ON B.col2 = C.col2 
    

    위와 같은 결과가 실행되어 결과를 제공합니다. 두 번째 조인 조건에서 B 테이블의 B.col2 조건을 사용하므로 첫 번째 조인 하위 쿼리 col1, col2에서 두 개의 열이 사용됩니다. select 절에서 세 테이블의 모든 열을 제공하는 '*' 연산자를 제공 할 수 있습니다. 그러나 조인은 이러한 방식으로 코딩되므로 조인의 하위 쿼리에서 연산자를 사용하지 않아야합니다.
    두 쿼리 모두 큰 차이는 없지만 첫 번째 논리는 두 번째 쿼리보다 빠르게 실행됩니다. 두 번째 논리에서는 두 개의 하위 쿼리를 사용하여 데이터베이스에서 여러 번 검색하고 첫 번째 논리보다 조금 느린 결과를 제공합니다.

    질문이 있으시길 바랍니다. 어떤 질문이라도 질문이 있으시면 언제든지