WHERE 절은 IN과 JOIN 이전 또는 이후에 더 잘 실행됩니다.
이 기사를 읽었습니다.SELECT 문의 논리적 처리 순서
기사의 끝 부분은 WHERE에 작성되었으며 JOIN 조항은 WHERE 이전에 고려해야 합니다.
1,000만 개의 레코드가 있는 마스터 테이블과 5,000만 개의 레코드가 있는 상세 테이블(마스터 테이블(FK) 참조)이 있다고 가정해 보겠습니다.마스터 테이블의 PK에 따라 100개의 세부 테이블 레코드만 원하는 쿼리가 있습니다.
이 상황에서 WHERE 전에 ON 및 JOIN 실행?가입 후 5억 개의 레코드를 보유하고 있으며 어디에 적용할 수 있습니까? 아니면 먼저 신청한 후 가입하고 고려할 수 있습니까?두 번째 답변이 사실이라면 상위 기사와 일치하지 않습니까?
감사해요.
내부 조인 또는 왼쪽 조인의 왼쪽 테이블의 경우, 최적화 도구는 실제 어떤 유형의 물리적 조인이든 실제로 수행하기 전에 먼저 필터링을 수행하는 것이 더 낫다는 것을 알게 될 것입니다. 따라서 더 나은 물리적 조인 순서가 분명히 존재합니다.
서브쿼리의 애그리게이트와 같이 SQL을 사용하여 이 작업을 어느 정도 제어할 수 있습니다(또는 방해할 수도 있습니다).
쿼리에서 제약 조건을 처리하는 논리적 순서는 알려진 불변 변환에만 따라 변환될 수 있습니다.
그래서:
SELECT *
FROM a
INNER JOIN b
ON a.id = b.id
WHERE a.something = something
AND b.something = something
여전히 논리적으로 다음과 같습니다.
SELECT *
FROM a
INNER JOIN b
ON a.id = b.id
AND a.something = something
AND b.something = something
그리고 그들은 일반적으로 동일한 실행 계획을 가질 것입니다.
반면에:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
WHERE a.something = something
AND b.something = something
다음과 같지 않습니다.
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
AND a.something = something
AND b.something = something
따라서 옵티마이저는 이를 동일한 실행 계획으로 변환하지 않습니다.
옵티마이저는 매우 영리하며 뷰 축소 및 인라인 테이블 값 함수를 비롯하여 특정 유형의 Aggregate를 통해 객체를 상당히 성공적으로 이동할 수 있습니다.
일반적으로 SQL을 작성할 때 SQL은 이해하기 쉽고 유지관리가 가능하며 정확해야 합니다.실행 효율성 측면에서 최적화 도구가 선언형 SQL을 허용 가능한 성능의 실행 계획으로 전환하는 데 어려움을 겪는 경우 코드를 단순화하거나 적절한 인덱스 또는 힌트를 추가하거나 단계별로 분류하여 보다 신속하게 수행할 수 있습니다. 이 모든 것이 연속적인 침입 순서로 이루어집니다.
그건 중요하지 않아.
논리적 처리 순서는 실제 처리 순서와 상관없이 항상 준수됩니다.
내부 조인과 WHERE 조건은 효과적으로 연관성과 교환성이 있으므로(따라서 ANSI-89 "join in the where" 구문) 실제 순서는 중요하지 않습니다.
논리적 순서는 외부 조인과 더 복잡한 쿼리에서 중요해집니다. 외부 테이블에 WHERE를 적용하면 논리가 완전히 바뀝니다.
다시 말하지만, 쿼리 의미론이 논리적 처리 순서를 따름으로써 유지되는 한 옵티마이저가 내부적으로 어떻게 이를 수행하는지는 중요하지 않습니다.
그리고 여기서 핵심 단어는 "optimizer"입니다: 그것은 정확히 그것이 말하는 것을 합니다.
방금 쿼리 옵티마이저에서 폴 화이트의 훌륭한 시리즈를 다시 읽고 이 질문을 기억했습니다.
문서화되지 않은 명령을 사용하여 특정 변환 규칙을 비활성화하고 적용된 변환에 대한 통찰력을 얻을 수 있습니다.
(바라건대!) 분명한 이유로 개발 인스턴스에 대해서만 이 작업을 수행하고 캐시에서 최적이 아닌 계획을 다시 활성화하고 제거해야 합니다.
USE AdventureWorks2008;
/*Disable the rules*/
DBCC RULEOFF ('SELonJN');
DBCC RULEOFF ('BuildSpool');
SELECT P.ProductNumber,
P.ProductID,
I.Quantity
FROM Production.Product P
JOIN Production.ProductInventory I
ON I.ProductID = P.ProductID
WHERE I.ProductID < 3
OPTION (RECOMPILE)
이 두 규칙을 사용하지 않으면 데카르트 조인 및 필터링이 수행되는 것을 볼 수 있습니다.
/*Re-enable them*/
DBCC RULEON ('SELonJN');
DBCC RULEON ('BuildSpool');
SELECT P.ProductNumber,
P.ProductID,
I.Quantity
FROM Production.Product P
JOIN Production.ProductInventory I
ON I.ProductID = P.ProductID
WHERE I.ProductID < 3
OPTION (RECOMPILE)
활성화된 경우 술어가 인덱스 검색으로 바로 밀리기 때문에 조인 작업에 의해 처리되는 행 수가 줄어듭니다.
정의된 순서가 없습니다.SQL 엔진은 최적화 프로그램에서 선택한 실행 전략에 따라 작업을 수행할 순서를 결정합니다.
당신이 잘못 읽은 것 같습니다.ON
~하듯이IN
그러나 문서에 표시된 순서는 정확합니다(어쨌든 MSDN임이 분명합니다).ON
그리고.JOIN
앞에 됩니다.WHERE
한 이유로WHERE
는 때에얻임결시집필적합니다용야해터로 인해 얻은 .JOINS
이 기사는 논리적 실행 순서라고만 말하고 문단 끝에도 이 행을 추가합니다;)
"문의 실제 물리적 실행은 쿼리 프로세서에 의해 결정되며 이 목록에서 순서가 달라질 수 있습니다."
언급URL : https://stackoverflow.com/questions/5463101/where-clause-better-execute-before-in-and-join-or-after
'programing' 카테고리의 다른 글
PHP에서 DEFINE vs 변수 (0) | 2023.08.29 |
---|---|
구분 기호로 판다 데이터 프레임 열 분할 (0) | 2023.08.29 |
Powershell의 개별 파일 형식 목록 (0) | 2023.08.29 |
도커 구성을 위해 환경 변수를 전달하는 방법 (0) | 2023.08.29 |
브라우저 자동 완성/수정 양식이 Ajax 요청에서 작동하지 않음 (0) | 2023.08.29 |