[SQL] 절과 절에서 테이블 조인을 떠날 때 경우의 차이점은 무엇입니까?
SQL절과 절에서 테이블 조인을 떠날 때 경우의 차이점은 무엇입니까?
SQL1 :
select t1.f1,t2.f2
from t1
left join t2 on t1.f1 = t2.f2 and t1.f2=1 and t1.f3=0
SQL2 :
select t1.f1,t2.f2
from t1
left join t2 on t1.f1 = t2.f2
where t1.f2=1 and t1.f3=0
차이점은,이 같은 반환 결과는 어디 절에 무엇입니까? 과의 차이는 무엇인가? DBMS는 그들에게 같은 방법으로 실행 하는가? 감사.
해결법
-
==============================
1.WHERE 절은 전체 결과 집합에 적용; (가) 문제의 가입에 온 절에만 적용됩니다.
WHERE 절은 전체 결과 집합에 적용; (가) 문제의 가입에 온 절에만 적용됩니다.
주어진 예에서, 가입의 내측에 분야에 관한 추가적인 조건이 모두 - 그래서이 예에서, 두 개의 쿼리 효과적으로 동일하다.
당신이 가입의 바깥 쪽의 테이블에 값에 대한 조건을 포함했다 그러나, 그것은 상당한 차이를 만들었을 것입니다.
http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause : 당신은이 링크에서 자세한 내용을 얻을 수 있습니다
예를 들면 :
select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 and t2.f4=1 select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 where t2.f4=1
- 다른 것들을 - 내부는 T2로 조인 후자 효과적으로 다시 설정 하였지만 전 의지, F4가 1 T2 레코드 가입 떠났다.
-
==============================
2.(가) 조건이 두 번째보다 더 구체적 조인으로 첫 번째 쿼리가 더 빨리 두 번째보다 : 그것은 당신이 where 절에 필터링 할 것이라는 점을 반환 기록에 의미가 없습니다 (이것은 모든 - 쿼리 1에이를 반환하지 않는 더 나은 것 )
(가) 조건이 두 번째보다 더 구체적 조인으로 첫 번째 쿼리가 더 빨리 두 번째보다 : 그것은 당신이 where 절에 필터링 할 것이라는 점을 반환 기록에 의미가 없습니다 (이것은 모든 - 쿼리 1에이를 반환하지 않는 더 나은 것 )
어쨌든 정말 쿼리 최적화 따라 달라집니다.
아래를 보라 :
A는 빠르게 WHERE 이상의 조인?
-
==============================
3.두 쿼리는 동일하지 않습니다.
두 쿼리는 동일하지 않습니다.
마크 베니 스터는 where 절은 전체 결과 집합에 적용되지만 절에 조인을 적용한다는 지적에 맞았다.
SQL 1 좌 조건을 가입하기 위해 귀하의 경우, 필터는 오른쪽에 참여하지만, 필터링 WHERE 왼쪽은 항상 어떤 전에 반환됩니다. 더 있기 때문에 모든 T1의 조건은 항상 반환되지이다.
SQL 2에서 왼쪽 조건 필터를 오른쪽에 보여주는 몇 가지 결과를 가입하지만, 모든 것을 다시 T1이 반환됩니다. 하지만 이번에는 상황이 떨어져 T1의 일부 레코드를 필터링 할 수있다 WHERE.
INSERT INTO`t1` (f1```f2``f3`) VALUES (1,1,1); INSERT INTO`t2` (`f3`) VALUES (1);
서로 다른 논리를 가리 키 때문에 쿼리가 그 기반으로 작성 그것은 우리에게 큰 힘과 유연성을 제공해야합니다.
내부는 예는 옵티마이을 확인할 수 있도록 그러나 같은 결과를 반환 가입하세요.
-
==============================
4.그래서 심지어 INNER이 (가) 과정을 가입하는 동안 그들은 이미 제외 할 수 있도록 조항이 옵티 마이저에 의해 rearrranged 술어를 가질 수 WHERE와 쿼리 가입하세요, 관계형 대수는 WHERE 절에서 술어의 호환성을 허용하고 내부는 가입하세요.
그래서 심지어 INNER이 (가) 과정을 가입하는 동안 그들은 이미 제외 할 수 있도록 조항이 옵티 마이저에 의해 rearrranged 술어를 가질 수 WHERE와 쿼리 가입하세요, 관계형 대수는 WHERE 절에서 술어의 호환성을 허용하고 내부는 가입하세요.
난 당신이 가능한 가장 읽기 쉬운 방식으로 쿼리를 작성하는 것이 좋습니다.
때때로 이것은 내부가 상대적으로 "불완전"가입하고 단순히 더 쉽게 유지 보수 기준을 필터링의 목록을 만들기 위해 WHERE의 기준의 일부를 퍼팅이 포함되어 있습니다.
이 링크에서 자세한 내용을 얻을 수 있습니다 : http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause
예를 들어, 대신 :
SELECT * FROM Customers c INNER JOIN CustomerAccounts ca ON ca.CustomerID = c.CustomerID AND c.State = 'NY' INNER JOIN Accounts a ON ca.AccountID = a.AccountID AND a.Status = 1
쓰다:
SELECT * FROM Customers c INNER JOIN CustomerAccounts ca ON ca.CustomerID = c.CustomerID INNER JOIN Accounts a ON ca.AccountID = a.AccountID WHERE c.State = 'NY' AND a.Status = 1
그러나 물론, 따라 달라집니다.
-
==============================
5.SQL 구문에 대해 생각 할 때 SQL 작업의 논리적 순서를 이해하는 것이 중요합니다. 조인 연산자 (그리고 관련 참가할 ON이 속해) FROM 절. FROM 절은 (optimisers 여전히 재주문 가지로 선택할 수 있습니다) 논리적으로 실행하는 최초의 작업입니다.
SQL 구문에 대해 생각 할 때 SQL 작업의 논리적 순서를 이해하는 것이 중요합니다. 조인 연산자 (그리고 관련 참가할 ON이 속해) FROM 절. FROM 절은 (optimisers 여전히 재주문 가지로 선택할 수 있습니다) 논리적으로 실행하는 최초의 작업입니다.
당신의 예에서, 정말 차이가 아니라, 내가 블로그 게시물에서 (예를 외부 조인의 ON과 WHERE 사이의 차이에 대한이 블로그 게시물에 표시된 Sakila 데이터베이스를 사용했습니다으로는 하나를 구성하기 쉽다 ) :
첫 번째 쿼리
SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id) FROM actor a LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id WHERE fa.film_id < 10 GROUP BY a.actor_id, a.first_name, a.last_name ORDER BY count(fa.film_id) ASC;
수익률 :
ACTOR_ID FIRST_NAME LAST_NAME COUNT -------------------------------------- 194 MERYL ALLEN 1 198 MARY KEITEL 1 30 SANDRA PECK 1 85 MINNIE ZELLWEGER 1 123 JULIANNE DENCH 1
우리가 WHERE 절에서 외부 조인 된 테이블을 필터링하기 때문에, LEFT 효과적으로 내부에 가입되어 있었다 JOIN. 왜? 우리가 영화에서 재생되지 않은 배우가 있다면, fa.film_id 것 그 배우의 유일한 행이 NULL이고, fa.film_id <10 술어 따라서 NULL를 얻을 것 때문에. 그러한 배우가 단지 내부와 마찬가지로, 결과에서 제외됩니다 가입하세요.
두 번째 쿼리
SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id) FROM actor a LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id AND fa.film_id < 10 GROUP BY a.actor_id, a.first_name, a.last_name ORDER BY count(fa.film_id) ASC;
수익률 :
ACTOR_ID FIRST_NAME LAST_NAME COUNT ----------------------------------------- 3 ED CHASE 0 4 JENNIFER DAVIS 0 5 JOHNNY LOLLOBRIGIDA 0 6 BETTE NICHOLSON 0 ... 1 PENELOPE GUINESS 1 200 THORA TEMPLE 1 2 NICK WAHLBERG 1 198 MARY KEITEL 1
fa.film_id <10 술어가 왼쪽의 일부 술어 ON의 JOIN을하기 때문에 이제 영화가없는 배우가 결과에 포함됩니다
결론
그들은 논리적으로 가장 의미가 어디에 항상 술어를 배치합니다.
-
==============================
6.1)
1)
SQL1: select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 **and** t1.f2=1 and t1.f3=0
이것에서는, 파서는이 3 개 개의 조건 (T2)의 각 행에 (T1)의 각 행을 검사 할 것이다. 빠른 결과를 얻기.
2) SQL2 : 선택 t1.f1, T1로부터 t2.f2가 t1.f1 = T2 t2.f2에 가입 왼쪽 여기서 ** ** t1.f2 = 1 = 0 t1.f3
이러한면에서, 가입 만 1 조건을 가지고, 결과는 그 두 조건을 필터링 조인에서 얻었다. 그리고 1 쿼리보다 더 많은 시간이 소요됩니다.
http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause : 당신은이 링크에서 자세한 내용을 얻을 수 있습니다
from https://stackoverflow.com/questions/8311096/whats-the-difference-between-where-clause-and-on-clause-when-table-left-join by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] PostgreSQL의에서 문자열 값 (같은 평가) 내부 쿼리를 실행할 수있는 방법이 있습니까? (0) | 2020.04.21 |
---|---|
[SQL] 문자열 열이 절 사이에 SQL (0) | 2020.04.21 |
[SQL] SQL 서버 * = 연산자? (0) | 2020.04.21 |
[SQL] 어떻게 SQL Server의 시간 필드를 요약하기 (0) | 2020.04.20 |
[SQL] java.sql.SQLException이있다 : mysql : 없음 적합한 드라이버는 JDBC을 찾을 수 없습니다 // localhost를 : 3306 / DBNAME [중복] (0) | 2020.04.20 |