programing

Oracle Joins - 기존 구문 VS ANSI 구문 비교

javamemo 2023. 3. 6. 20:38
반응형

Oracle Joins - 기존 구문 VS ANSI 구문 비교

프리암블

현재 Oracle 질문에 대해 너무 많은 괴짜들이 "+ 연산자를 사용하지 말고 JOIN 구문을 사용합니다."라고 코멘트하고 있습니다.

질문.

둘 다 잘 되는 것 같아요.하지만 그것들을 사용하는 것의 진짜 차이점은 무엇일까요?나는 경험에서 나온 대답을 더 환영한다.

  1. 사용 중 응용 프로그램, 성능 등의 제한과 관련이 있습니까?
  2. 나에게 무엇을 제안하겠습니까?

Oracle 설명서에서 읽은 내용은 있지만 포괄적인 정보를 이해하거나 이해하기에는 충분하지 않습니다.

주의: 200개 이상의 패키지와 프로시저를 이행할 예정입니다.키워드를 (+) 대신 사용하는 경우는,

  1. 또한 개서를 할 수 있는 프리웨어 툴이 있습니까?

샘플 투고

┌───────────────────────────────────┬─────────────────────────────────────────────┐
│ INNER JOIN - CONVENTIONAL         │ INNER JOIN - ANSI SYNTAX                    │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ SELECT                            │ SELECT                                      │
│      emp.deptno                   │       ename,                                │
│ FROM                              │       dname,                                │
│      emp,                         │       emp.deptno,                           │
│      dept                         │       dept.deptno                           │
│ WHERE                             │ FROM                                        │
│      emp.deptno = dept.deptno;    │       scott.emp INNER JOIN scott.dept       │
│                                   │       ON emp.deptno = dept.deptno;          │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ LEFT OUTER JOIN - CONVENTIONAL    │ LEFT OUTER JOIN - ANSI SYNTAX               │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ SELECT                            │ SELECT                                      │
│      emp.deptno                   │      ename,                                 │
│ FROM                              │      dname,                                 │
│      emp,                         │      emp.deptno,                            │
│      dept                         │      dept.deptno                            │
│ WHERE                             │ FROM                                        │
│      emp.deptno = dept.deptno(+); │      scott.emp LEFT OUTER JOIN scott.dept   │
│                                   │      ON emp.deptno = dept.deptno;           │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ RIGHT OUTER JOIN - CONVENTIONAL   │ RIGHT OUTER JOIN - ANSI SYNTAX              │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ SELECT                            │ SELECT                                      │
│      emp.deptno                   │      ename,                                 │
│ FROM                              │      dname,                                 │
│      emp,                         │      emp.deptno,                            │
│      dept                         │      dept.deptno                            │
│ WHERE                             │ FROM                                        │
│      emp.deptno(+) = dept.deptno; │      scott.emp RIGHT OUTER JOIN scott.dept  │
│                                   │      ON emp.deptno = dept.deptno;           │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ FULL OUTER JOIN - CONVENTIONAL    │ FULL OUTER JOIN - ANSI SYNTAX               │
├───────────────────────────────────┼─────────────────────────────────────────────┤
│ SELECT                            │ SELECT                                      │
│      *                            │      *                                      │
│ FROM                              │ FROM                                        │
│      emp,                         │      scott.emp FULL OUTER JOIN scott.dept   │
│      dept                         │      ON emp.deptno = dept.deptno;           │
│ WHERE                             │                                             │
│      emp.deptno = dept.deptno(+)  │                                             │
│ UNION ALL                         │                                             │
│ SELECT                            │                                             │
│      *                            │                                             │
│ FROM                              │                                             │
│      emp,                         │                                             │
│      dept                         │                                             │
│ WHERE                             │                                             │
│      emp.deptno(+) = dept.deptno  │                                             │
│      AND emp.deptno IS NULL;      │                                             │
└───────────────────────────────────┴─────────────────────────────────────────────┘

PS: 그룹화된 모든 업데이트에 대한 답변 요약을 읽습니다.

구문으로 「」으로 해 주세요.SQL ANSI를 사용합니다.을 사용하다

ANSI를 사용하다멀티컬럼의 외부 결합에서 (+)를 잊으면 일반 결합이 되지 않습니다.
과거에는 ANSI 구문을 사용하는 버그가 있었지만, 최신 11.2 또는 12.1을 사용하는 경우는 이미 수정이 끝난 상태여야 합니다.
를 더 잘 - 처럼. - SchmitzIT부문은 ANSI 구문은 SQL 표준의 일부이며 다른 RDBMS 제품을 사용할 때 유용합니다.

11g에서는 ANSI join 구문을 사용해야 합니다.이 기능은 보다 유연하며(전체 외부 조인 및 분할 조인 지원), 설명서에 기재되어 있는 바와 같이 다음과 같습니다.

Oracle은 앞의 예에 나와 있는 보다 유연한 FROM 절 join 구문을 사용할 것을 강력히 권장합니다.

그만하면 충분해.

회답의 그룹화

  1. (외부 조인이든 아니든) 암묵적인 조인이 아닌 명시적인 조인을 사용하면 암묵적인 조인을 사용하여 실수로 데카르트 제품을 작성하기 쉬워집니다.명시적 JOIN을 사용하면 "실수로" 생성할 수 없습니다.관련된 테이블이 많을수록 가입 조건이1개 누락될 위험이 높아집니다.
  2. 기본적으로 (+)는 ANSI Join에 비해 크게 제한됩니다.또한 ANSI join 구문은 모든 주요 DBMS에서 지원되는 반면 Oracle에서만 사용할 수 있습니다.
  3. SQL은 ANSI 구문으로의 이행 후 성능이 향상되지 않습니다.구문이 다를 뿐입니다.
  4. Oracle은 앞의 예에 나와 있는 보다 유연한 FROM 절 join 구문을 사용할 것을 강력히 권장합니다.과거에는 ANSI 구문을 사용하는 버그가 있었지만, 최신 11.2 또는 12.1을 사용하는 경우는 이미 수정이 끝난 상태여야 합니다.
  5. JOIN 연산자를 사용하면 SQL 코드가 ANSI에 준거하고 있는지 확인할 수 있으므로 프론트 엔드 애플리케이션을 다른 데이터베이스 플랫폼으로 보다 쉽게 이식할 수 있습니다.
  6. 결합 조건은 각 테이블에서 선택성이 매우 낮고 이론적 교차곱에서 튜플에서 선택성이 높습니다.여기서 스테이트먼트의 조건은 보통 선택성이 훨씬 높아집니다.
  7. Oracle은 내부적으로 ANSI 구문을 (+) 구문으로 변환하며, 실행 계획의 술어 정보 섹션에서 이러한 현상을 확인할 수 있습니다.

12c 엔진에서 ANSI 구문을 사용할 때 발생할 수 있는 피트폴

12c의 JOIN에 버그가 있을 가능성도 포함.여기를 참조해 주세요.

후속 조치:

Quest SQL optimizer tool구문으로 .

다른 이유와는 별도로 JOIN 연산자를 사용하면 SQL 코드가 ANSI에 준거하여 프론트 엔드 애플리케이션을 다른 데이터베이스 플랫폼으로 쉽게 이식할 수 있습니다.

관례상 항상 ANSI 구문을 사용해야 합니다.패키지와 절차에 대한 재작업은 하지 않는 것이 좋습니다.이러한 스크립트를 개별적으로 유지보수할 때 문제를 해결할 수 있습니다.구문에 의한 플랜의 차이는 없습니다.

Quest SQL optimizer는 더 나은 계획을 찾기 위해 가능한 모든 조합으로 다시 씁니다.따라서 100개 이상의 결과에서 SQL 하나를 검색해야 합니다.

선택성에 따라 술어 분리

쿼리를 조인 조건과 옵티마이저에게 추가 힌트를 줄 수 있는 조건으로 구분합니다.결합 조건은 각 테이블에서 선택성이 매우 낮고 이론적 교차곱에서 튜플에서 선택성이 높습니다.여기서 스테이트먼트의 조건은 보통 선택성이 훨씬 높아집니다.

왼쪽의 각 행에 대한 결합 조건에서는 오른쪽(또는 그 반대)에 값이 있을 가능성이 높습니다.따라서 이러한 조건은 2개의 테이블에서 결과를 결합하는 것은 좋지만 결과 집합에서 각 개별 테이블에서 값을 제거하는 데는 그다지 도움이 되지 않습니다.

보통 여기서 구를 사용하여 결과 집합에서1개의 테이블에서 개별 행을 삭제할 수 있습니다.

(인간!) 옵티마이저를 위한 힌트

따라서 개별 테이블의 조건을 먼저 실행하고 결과 집합에서 가능한 한 많은 행을 제거하는 것이 좋습니다.그런 다음 결합 조건을 사용하여 나머지 행을 결합할 수 있습니다.

Oracle 옵티마이저가 SQL 문의 조건 위치를 쿼리를 최적화하기 위한 힌트로 실제로 사용하는지는 명확하지 않습니다.표 통계의 확실한 사실(Oracle이 11g R1에서 서로 다른 조인을 처리하는 방식에 약간의 변화가 있었습니다. 자세한 내용은 Oracle Optimizer 팀의 게시물을 참조하십시오.)에 더 관심이 있을 것입니다.

적어도 인간으로서 쿼리를 이해하고 최적화하려고 할 때 단일 테이블에 선택성이 있는 스테이트먼트를 아는 것은 매우 도움이 됩니다., 구에 예를 들면, ON 의 경우)도고려할 가 있습니다.ON (a.x=b.x AND a.y=b.y ) : )에 .조건이 얼마나 선택적인지 확인해봐

결론

기존 쿼리의 경우 구문을 그대로 유지합니다.새 쿼리를 만들거나 기존 쿼리를 리팩터링할 때는 "JOIN ON" 구문을 사용하여 선택성에 대한 술어를 정렬해 보십시오. 단일 테이블에서 선택할 수 없는 경우에는 ON 부분에, 그렇지 않은 경우에는 WHERE 부분에 배치합니다.

Outer join에서 사용되는 (+) 기호는 Outer join의 Oracle 구문입니다.

신뢰할 수 있는 오라클 소스에서 수집한 정보에서 200개 이상의 패키지가 있고 내부적으로 Oracle이 ANSI 구문에서 Oracle 구문으로 변환하기 때문에 기존 패키지에 대한 Oracle 외부 결합 구문(+)을 유지할 수 있음을 알 수 있었습니다.

향후 (+) 연산자 사용에 제한이 있는 경우 ANSI 구문을 사용하십시오.

(+) 기호의 외부 결합에 대한 자세한 설명은 이행을 결정하는 데 도움이 될 수 있는 링크를 참조하십시오.

Oracle Outer Join 구문 및 ANSI 구문

(+) 외부 결합 사용에 관한 제한 사항

Oracle 외부 결합에 대한 자세한 정보

(+) Oracle JDBC 드라이버를 사용하는 경우 Java에서 권장되는 외부 참여 오퍼레이터

서로 다른 프로젝트에서 두 가지 방법을 모두 사용했으며, 저는 더 선호합니다.JOIN구문을 사용합니다.

  • 에서는 결합 조건에 대한 명확한 분리가 있습니다.ON의 절 및 필터 조건WHERE절을 클릭합니다.
  • 조인 수가 많은 대규모 쿼리를 읽고 유지 관리하는 것이 더 쉽습니다.

일부 코멘트에서는 (+) 구문은 완전한 외부 결합을 허용하지 않는다고 합니다.문제가 없습니다(왼쪽 외부 결합) UNION ALL(오른쪽 외부 결합).

다른 사람들은 성능이 전환의 이유라고 말했습니다.특히 SQL에서는 그런 말도 안 되는 소리들이 많죠.물론 몇 가지 가이드라인이 있지만 모든 쿼리 및 데이터베이스에는 고유한 특성이 있으므로 일반적인 상황이 아닌 특정 상황에 맞게 조정해야 합니다.

(+)에서 전환해야 하는 이유는 표준이 아닐 뿐만 아니라 새로운 명시적 구문(http://docs.oracle.com/cd/E16655_01/server.121/e17209/queries006.htm#SQLRF52354)과는 달리 제한사항이 있기 때문입니다.여기서부터 읽기 시작합니다. "Oracle은 Oracle join 연산자가 아닌 FROM 절 OUTER JOIN 구문을 사용할 것을 권장합니다."

직장에서의 경험담, 사용법JOIN보다는(+)는, 보다 심플하고, 알기 쉽고, 보다 보기 좋고, 솔루션과의 연계성이 우수합니다.다양한 데이터베이스 선택(동의어 전체)을 사용하여 다수의 테이블(1000개 이상의 테이블, 20억 개 이상의 행이 있는 테이블)을 빅 데이타베이스에 포함시키면, 큰 차이를 느낄 수 있습니다.

나는 지난주까지 ANSI 가입을 지지했다.내가 선택한 사람 중 한 명에게서 이상한 행동을 눈치챘어Oracle 버그 베이스를 파헤친 후 Oracle은 ANSI 조인을 기본적으로 지원하지 않는다는 것을 알게 되었습니다.- ANSI 조인은 (+) 표기로 변환되어 처리됩니다.그리고 이 번역에는 허용할 수 없는 오류가 몇 가지 있습니다.고객이 패치를 적용하지 않고 있으며, 12c 버전에서도 새로운 버그가 몇 가지 도입되었기 때문에 받아들일 수 없습니다.이것은 3개의 테이블, 1개의 레코드, 2개의 외부 결합으로 이루어진 매우 단순한 테스트 케이스입니다.남자들은 자동 회귀 테스트를 전혀 하지 않는 것 같아

언급URL : https://stackoverflow.com/questions/18891148/oracle-joins-comparison-between-conventional-syntax-vs-ansi-syntax

반응형