-
22-08-2019 - |
문제
다음 SQL 쿼리를 실행하면
SELECT *
FROM A
LEFT JOIN B
ON A.foo=B.foo
WHERE A.date = "Yesterday"
그렇습니다 WHERE
진술은 전후에 평가됩니다 JOIN
?
이후에,이 진술을 작성하는 더 좋은 방법은 무엇입니까? A
~에서 "Yesterday"
가입합니다 B
?
해결책
데이터베이스에 따라 다릅니다.
SQL Server에서 실행 : SET SHOWPLAN_ALL ON
그런 다음 쿼리를 실행하면 실행될 때 어떤 일이 발생하는지에 대한 아이디어를 얻게됩니다.
다른 팁
SQL이 선언적 언어이므로 "평가"에 대한 귀하의 아이디어는 정확하지 않습니다.
BTW 쿼리 실행 계획을 볼 수 있습니다. MySQL에서 쿼리를 키워드로 접두사하십시오 describe
실행 계획을 보려면.
의미 적으로 : 가입 후. 그러나이 경우 타이밍에는 차이가 없습니다. 결합의 왼쪽에 있기 때문입니다.
이미 가지고 있듯이 ""어제 "의 A의 행만 B에 합류합니다".
Optimizer는 관계형 대수의 동등성에 따라 운영 순서를 자유롭게 재구성 할 수 있습니다.
이것은 A.date = "어제"만 반환하고 B에 합류하여 Foo에서 일치 할 수 있습니다.
SELECT * FROM A
LEFT JOIN B
ON A.foo=B.foo
WHERE A.date="Yesterday"
이것은 모든 기준에 관계없이 모든 A를 반환하고 B에 합류하여 A.date = "어제"에 따라 Foo에서 일치합니다.
SELECT * FROM A
LEFT JOIN B
ON A.foo=B.foo
AND A.date="Yesterday"
쿼리를 만족시키기위한 운영 순서는 특정 데이터베이스의 쿼리 최적화기의 변덕이 왜 결정됩니다. 쿼리 옵티마이저는 쿼리에서 수집 할 수있는 내용과 데이터베이스에 대한 모든 통계 (테이블의 추기경 및 특정 데이터 분포를 포함 할 수 있음)를 기반으로 좋은 "쿼리 플랜"(운영 세트)을 제품으로 선택합니다. .
귀하의 경우, 답은 A.Date에 대한 보조 지수가 있는지 여부에 따라 다를 수 있습니다.
쿼리 최적화 상당히 풍부한 주제. 사용하는 데이터베이스에 대한 문서는 그것에 대해 더 많은 말을 할 것입니다.
인덱스 및 통계에 따라 다릅니다.
쿼리의 실행 경로를 표시하여 (있는 경우) 최적화를 적용 해야하는 위치를 결정해야합니다.
SQL Server에서 :
일반적으로 조인 조인은 조항이있는 곳 이전에 평가됩니다.
조인 부분에 필터가 필요한 복잡한 결합의 경우, 나는 결합과 함께 작성합니다.
SELECT *
FROM A
LEFT JOIN B
ON A.Foo1 = B.Foo1
And A.Date = 'Yesterday'
OUTER JOIN C
ON B.Foo2 = C.Foo2
JOIN D
ON B.Foo3 = D.Foo3
SELECT *
FROM (SELECT * FROM A WHERE Date = 'Yesterday') A
LEFT JOIN B
ON A.Foo1 = B.Foo1
OUTER JOIN C
ON B.Foo2 = C.Foo2
JOIN D
ON B.Foo3 = D.Foo3