ANSI JOIN 쿼리와 비 ANSI JOIN 쿼리의 성능이 다릅니까?
T-SQL 저장 프로시저의 비즈니스 로직을 7000줄까지 보유하고 있으며, 대부분은 다음과 같은 JOIN 구문을 가지고 있습니다.
SELECT A.A, B.B, C.C
FROM aaa AS A, bbb AS B, ccc AS C
WHERE
A.B = B.ID
AND B.C = C.ID
AND C.ID = @param
이러한 쿼리를 다음과 같이 대체하면 성능이 향상됩니까?
SELECT A.A, B.B, C.C
FROM aaa AS A
JOIN bbb AS B
ON A.B = B.ID
JOIN ccc AS C
ON B.C = C.ID
AND C.ID = @param
아니면 그들이 같습니까?
두 쿼리는 동일하지만 두 번째는 ANSI-92 SQL 구문이고 첫 번째는 join 절이 포함되지 않은 이전 SQL 구문입니다.그들은 확인하고 싶겠지만 정확히 동일한 내부 쿼리 계획을 작성해야 합니다.
몇 가지 이유로 ANSI-92 구문을 사용해야 합니다.
- JOIN 절을 사용하면 관계 로직과 필터 로직(WHERE)을 분리할 수 있으므로 더 깨끗하고 이해하기 쉽습니다.
- 이 쿼리와 상관없지만 이전 외부 조인 구문(+ 사용)이 모호하여 쿼리 결과가 구현에 종속되거나 쿼리를 전혀 해결할 수 없는 몇 가지 상황이 있습니다.ANSI-92에서는 이러한 문제가 발생하지 않습니다.
- 현재 대부분의 개발자와 DBA가 ANSI-92를 사용하고 있으므로 표준을 따라야 합니다.확실히 모든 최신 쿼리 도구는 ANSI-92를 생성할 것입니다.
- @gbn이 지적한 바와 같이 우발적인 교차 조인을 피하는 경향이 있습니다.
나 자신도 한동안 ANSI-92에 저항했는데, SQL을 모든 테이블의 데카르트식 대량 조인에 이어 필터링 작업으로 보는 것이 더 쉽기 때문입니다. SQL 쿼리가 무엇을 하고 있는지 파악하는 데 유용할 수 있는 정신적 기술입니다.하지만 저는 몇 년 전에 시대와 함께 움직일 필요가 있다고 결정했고 비교적 짧은 조정 기간 후에 저는 지금 그것을 강하게 선호합니다. 주로 위에 제시된 첫 번째 이유 때문입니다.ANSI-92 구문에서 벗어나거나 옵션을 사용하지 않는 유일한 장소는 암묵적으로 위험한 자연 조인입니다.
두 번째 구성은 SQL 커뮤니티에서 "고정 조인 구문"으로 알려져 있습니다.첫 번째 구성 AFAIK는 널리 받아들여지는 이름을 가지고 있지 않으므로 '오래된 스타일' 내부 조인 구문이라고 부릅니다.
일반적인 인수는 다음과 같습니다.
'전통적' 구문의 장점: 술어는 물리적으로 함께 그룹화되어 있습니다.WHERE를 일반적으로,를 더 할 수 절쿼, n-ary 관기절순계만서드의게는쉽기로읽를해고하이으리일쉽반적를특히▁in▁clausethe절-▁which▁order▁the순의서드-▁whatever▁to쿼는만▁generally리게를yhips▁partic▁query▁makes쉽▁andar▁read▁nstand▁(,▁under▁andON고정된 구문의 절은 술어를 분산시킬 수 있으므로 시각적 거리에서 한 테이블 또는 열의 모양을 찾아야 합니다.
구문의 : ' 중 할 때 구문 곱('join'으로 알려져 있음)입니다.CROSS JOIN이러한 오류는 탐지 및 디버그하기가 까다로울 수 있습니다. 'join' 술어와 'filtering' 술어가 같이 묶입니다.WHERE서로 혼동을 일으킬 수 있는 절입니다.
두 쿼리는 동일합니다. 첫 번째는 비 ANSI JOIN 구문을 사용하는 것이고, 두 번째는 ANSI JOIN 구문을 사용하는 것입니다.ANSI JOIN 구문을 고수하는 것이 좋습니다.
그리고 예, LEFT OUTER JOIN(Btw는 ANSI JOIN 구문이기도 함)은 가입 중인 테이블에 일치하는 레코드가 없을 수 있는 경우에 사용할 항목입니다.
좋아요, 그들은 똑같이 실행합니다.저도 동의해요.많은 사람들과 달리 저는 오래된 관습을 사용합니다.SQL-92가 "이해하기 더 쉽다"는 것은 논란의 여지가 있습니다.40년 동안 프로그래밍 언어를 써온 저는 '읽기 쉬운'이 다른 관례보다 먼저 '시각적 예리함'(여기서 잘못 적용된 용어이지만 제가 사용할 수 있는 가장 좋은 문구)으로 시작한다는 것을 알고 있습니다.SQL을 읽을 때 가장 먼저 관심을 갖는 것은 어떤 테이블이 관련되어 있는지, 그 다음 어떤 테이블(가장 많이)이 곡물을 정의하는지입니다.그런 다음 데이터에 대한 관련 제약 조건과 선택된 속성에 관심이 있습니다.SQL-92는 대부분 이러한 아이디어들을 분리하지만, 잡음이 많은 단어들이 있습니다. 마음의 눈은 이것들을 해석하고 다루어야 하고, 그것은 SQL을 읽는 것을 더 느리게 만듭니다.
SELECT Mgt.attrib_a AS attrib_a
,Sta.attrib_b AS attrib_b
,Stb.attrib_c AS attrib_c
FROM Main_Grain_Table Mgt
,Surrounding_TabA Sta
,Surrounding_tabB Stb
WHERE Mgt.sta_join_col = Sta.sta_join_col
AND Mgt.stb_join_col = Stb.stb_join_col
AND Mgt.bus_logic_col = 'TIGHT'
시력!새 특성에 대한 쉼표를 앞에 배치합니다. 주석 코드도 쉽게 만듭니다. 함수 및 키워드에 대한 특정 대소문자 사용 표에 대한 특정 대소문자 사용 속성에 대한 특정 대소문자 사용 연산자 및 작업 FROM의 첫 번째 테이블 만들기 데이터의 입자를 나타냅니다. 결합할 첫 번째 테이블 만들기구체적이고 엄격한 제약 조건을 바닥에 띄웁니다.데이터베이스의 모든 테이블에 대해 3개의 문자 별칭을 선택하고 테이블을 참조하는 모든 위치에 별칭을 사용합니다.또한 해당 테이블의 여러 인덱스에 대한 접두사로 해당 별칭을 사용해야 합니다.1과 1/2 다스 중에 6개가 더 있죠, 그렇죠?그럴지도 모릅니다. 하지만 여러분이 ANSI-92 관례를 사용하고 있다고 해도(저처럼 그리고 앞으로도 그럴 것입니다), 여러분의 마음의 눈이 여러분이 보고 싶은 곳으로 향하고 여러분이 볼 필요가 없는 것들(특히 소음 단어)을 쉽게 피할 수 있도록 하기 위해 시각적인 예리한 원리, verticle alignment를 사용합니다.
둘 다 실행하고 쿼리 계획을 확인합니다.그들은 동등해야 합니다.
제 생각에 FROM 절은 제 SELECT 절이 작업할 행에 필요한 열을 결정하는 곳입니다.여기서 비즈니스 규칙이 표현되고 계산에 필요한 값이 같은 행에 표시됩니다.비즈니스 규칙은 송장을 가지고 있는 고객일 수 있으며, 그 결과 책임이 있는 고객을 포함한 송장 행이 생성됩니다.또한 고객과 동일한 우편 번호의 장소일 수 있으며, 결과적으로 서로 가까운 장소 및 고객 목록이 생성될 수 있습니다.
여기서 결과 집합에 있는 행의 중심성을 계산합니다.결국, 우리는 RDBMS에서 각 목록에 주제(엔티티)가 있고 각 행이 엔티티의 인스턴스가 되는 목록의 은유를 보여줍니다.행 중심이 이해되면 결과 집합의 엔터티가 이해됩니다.
From 절에 행이 정의된 후 개념적으로 실행되는 WHERE 절은 SELECT 절이 작동하는 데 필요하지 않은 행을 제거합니다(또는 필요한 행을 포함합니다).
조인 로직은 FROM 절과 WHERE 절 모두에서 표현될 수 있고, 복잡한 로직을 분할하고 정복하기 위해 절이 존재하기 때문에 FROM 절에 값을 포함하는 조인 로직을 넣기로 했습니다. 기본적으로 열에 값을 일치시키는 비즈니스 규칙을 열에 표현하는 것이기 때문입니다.
즉, 다음과 같은 WHERE 절은 작성하지 않습니다.
WHERE Column1 = Column2
저는 그것을 다음과 같이 FROM 절에 넣을 것입니다.
ON Column1 = Column2
마찬가지로, 우편 번호를 특정 우편 번호와 비교하는 것과 같이 열을 외부 값(열에 있을 수도 있고 없을 수도 있는 값)과 비교해야 하는 경우, 저는 본질적으로 이러한 행만 원한다고 말하고 있기 때문에 WHERE 절에 그것을 넣을 것입니다.
즉, 다음과 같은 FROM 절은 작성하지 않습니다.
ON PostCode = '1234'
저는 그것을 다음과 같이 WHERE 조항에 넣을 것입니다.
WHERE PostCode = '1234'
ANSI 구문은 적절한 절(ON 또는 WHERE)에 술어를 배치하거나 인접한 테이블 참조에 대한 ON 절의 선호도를 적용하지 않습니다.개발자는 이와 같은 엉망진창인 것을 자유롭게 쓸 수 있습니다.
SELECT
C.FullName,
C.CustomerCode,
O.OrderDate,
O.OrderTotal,
OD.ExtendedShippingNotes
FROM
Customer C
CROSS JOIN Order O
INNER JOIN OrderDetail OD
ON C.CustomerID = O.CustomerID
AND C.CustomerStatus = 'Preferred'
AND O.OrderTotal > 1000.0
WHERE
O.OrderID = OD.OrderID;
"ANSI-92를 생성할" 쿼리 도구에 대해 말하자면, 생성되었기 때문에 여기에 언급합니다.
SELECT 1
FROM DEPARTMENTS C
JOIN EMPLOYEES A
JOIN JOBS B
ON C.DEPARTMENT_ID = A.DEPARTMENT_ID
ON A.JOB_ID = B.JOB_ID
기존의 "제한 프로젝트 데카르트 제품"에서 벗어나는 유일한 구문은 외부 조인입니다.이 작업은 연관성이 없기 때문에 더 복잡합니다(자체 및 일반 조인 모두).적어도 외부 조인을 사용하여 쿼리를 현명하게 괄호로 묶어야 합니다.그러나 이 작업은 이국적인 작업입니다. 너무 자주 사용하는 경우 관계형 데이터베이스 클래스를 수강하는 것이 좋습니다.
언급URL : https://stackoverflow.com/questions/1599050/will-ansi-join-vs-non-ansi-join-queries-perform-differently
'programing' 카테고리의 다른 글
| 원래 레포의 복제본에서 포크로 푸시하려면 어떻게 해야 합니까? (0) | 2023.07.02 |
|---|---|
| "ASIF()" 문을 쿼리하는 방법은 mariaDB? (0) | 2023.07.02 |
| 해당 이름의 빈이 클래스 경로 리소스 [경로]에 이미 정의되어 있으며 재정의가 사용되지 않도록 설정되었습니다. (0) | 2023.07.02 |
| 정적 메서드는 스레드 안전합니까? (0) | 2023.07.02 |
| mysql-connector-python 쿼리 스크립트가 작동하지 않지만 PHP에서만 작동합니다. (0) | 2023.07.02 |