이 문서는 지원되지 않는 PostgreSQL 버전에 대한 것입니다.
다음에 대한 동일한 페이지를 보고 싶을 수도 있습니다.PostgreSQL : 문서 : 17 : 36.14. 사용자 정의 무지개 토토버전 또는 위에 나열된 다른 지원 버전 중 하나를 사용하세요.

40장. 확장SQL: 젠 토토

포스트그레왼쪽 단항을 지원합니다. 바로 단항 및 이진 연산자입니다. 연산자가 오버로드될 수 있습니다. 그 즉, 동일한 연산자 이름을 다른 연산자에 사용할 수 있습니다. 인수의 수와 유형이 다릅니다. 있는 경우 모호한 상황과 시스템이 올바른 결정을 내릴 수 없습니다. 연산자를 사용하면 오류가 반환됩니다. 타입캐스트를 해야 할 수도 있습니다. 어떤 연산자를 이해하는 데 도움이 되는 왼쪽 및/또는 오른쪽 피연산자 당신은 사용하려고 했어요.

모든 젠 토토는 기본 호출에 대한 "구문적 설탕"입니다. 실제 작업을 수행하는 기능; 따라서 먼저 젠 토토를 만들기 전에 기본 함수를 사용하세요. 그러나 젠 토토는아님단순한 구문 설탕, 쿼리에 도움이 되는 추가 정보를 전달하기 때문입니다. 플래너는 연산자를 사용하는 쿼리를 최적화합니다. 이것의 대부분 장은 추가 내용을 설명하는 데 전념할 것입니다. 정보.

다음은 두 개를 더하는 연산자를 생성하는 예입니다. 복소수. 우리는 이미 다음의 정의를 만들었다고 가정합니다. 유형 콤플렉스. 먼저 작업을 수행하는 함수가 필요합니다. 그럼 우리는 연산자를 정의할 수 있습니다:

CREATE FUNCTION complex_add(복합,복잡)
    반품 콤플렉스
    AS '$PWD/obj/complex.so'
    언어 'ㄷ';

젠 토토 만들기 + (
    leftarg = 복잡함,
    rightarg = 복잡함,
    프로시저 = complex_add,
    정류자 = +
);

이제 우리는 할 수 있습니다:

SELECT (a + b) AS c FROM test_complex;

+----------------+
|c |
+----------------+
|(5.2,6.05) |
+----------------+
|(133.42,144.95) |
+----------------+

우리는 여기서 이진 연산자를 생성하는 방법을 보여주었습니다. 생성하려면 단항 연산자인 경우 leftarg(왼쪽 단항의 경우) 중 하나를 생략하거나 rightarg(오른쪽 단항의 경우). 프로시저 절과 인수 절은 CREATE OPERATOR의 유일한 필수 항목입니다. 는 예제에 표시된 COMMUTATOR 절은 다음 항목에 대한 선택적 힌트입니다. 쿼리 최적화 프로그램. COMMUTATOR 및 기타에 대한 자세한 내용 최적화 프로그램 힌트가 아래에 나타납니다.

운영자 최적화 정보

저자:톰 레인이 작성함.

A 포스트그레스연산자 정의 시스템에 유용함을 알려주는 여러 선택적 절을 포함할 수 있습니다. 운영자가 어떻게 행동하는지에 관한 것입니다. 이 조항은 필요할 때마다 제공됩니다. 쿼리 실행 속도가 상당히 빨라졌습니다. 운영자. 하지만 제공하는 경우 해당 정보가 다음과 같은지 확인해야 합니다. 맞아! 최적화 절을 잘못 사용하면 다음과 같은 결과가 발생할 수 있습니다. 백엔드 충돌, 미묘하게 잘못된 출력 또는 기타 나쁜 것들. 당신은 할 수 있습니다 확실하지 않은 경우 항상 최적화 절을 생략하십시오. 그것; 유일한 결과는 쿼리가 쿼리보다 느리게 실행될 수 있다는 것입니다. 필요합니다.

추후에 추가적인 최적화 조항이 추가될 수 있습니다 버전포스트그레스. 그들 여기에 설명된 내용은 릴리스 6.5에서 이해되는 모든 내용입니다.

커뮤테이터

COMMUTATOR 절이 제공되면 다음과 같은 연산자의 이름을 지정합니다. 정의되는 연산자의 정류자. 우리는 그 운영자를 말한다 모든 경우에 (x A y)가 (y B x)와 같을 경우 A는 연산자 B의 정류자입니다. 가능한 입력 값 x,y. B는 또한 다음의 정류자이기도 합니다. A. 예를 들어 특정 항목에 대한 연산자 '<' 및 '' 데이터 유형은 일반적으로 서로의 정류자이며 연산자 '+'는 일반적으로 그 자체로 교환 가능합니다. 그러나 연산자 '-'는 일반적으로 그렇지 않습니다. 무엇이든 교환 가능합니다.

전환된 연산자의 왼쪽 인수 유형은 다음과 같습니다. 정류자의 올바른 인수 유형, 그 반대의 경우도 마찬가지입니다. 그래서 이름은 정류자 연산자가 전부입니다.포스트그레검색하려면 제공되어야 합니다. 정류자, 이것이 COMMUTATOR에 제공되어야 하는 전부입니다. 조항.

자체 교환 연산자를 정의할 때 다음을 수행하면 됩니다. 그것. 교환 연산자 쌍을 정의할 때 조금 더 까다롭습니다. 정의할 첫 번째 항목은 어떻게 참조할 수 있나요? 아직 정의하지 않은 다른 하나는 무엇입니까? 두 가지가 있습니다 이 문제에 대한 해결책:

  • 한 가지 방법은 첫 번째 항목에서 COMMUTATOR 절을 생략하는 것입니다. 정의한 젠 토토를 두 번째에 제공합니다. 운영자의 정의. 이후포스트그레스가환 젠 토토를 알고 있습니다 쌍으로 와서 두 번째 정의를 보면 자동으로 돌아가서 누락된 COMMUTATOR 절을 채웁니다. 첫 번째 정의에서.

  • 다른 더 간단한 방법은 다음을 포함하는 것입니다. 두 정의 모두 COMMUTATOR 절이 있습니다. 언제포스트그레첫 번째 정의를 처리합니다. COMMUTATOR가 존재하지 않는 젠 토토를 참조한다는 것을 인식하고, 시스템은 해당 운영자에 대한 더미 항목을 만듭니다. 시스템의 pg_operator 테이블. 이 더미 항목은 유효합니다. 젠 토토 이름, 왼쪽 및 오른쪽 인수 유형에 대한 데이터만, 및 결과 유형이 전부입니다.포스트그레이 시점에서 추론할 수 있습니다. 는 첫 번째 운영자의 카탈로그 항목은 이 더미 항목에 연결됩니다. 나중에 두 번째 연산자를 정의하면 시스템이 업데이트됩니다. 두 번째 추가 정보가 포함된 더미 항목 정의. 그 전에 더미 연산자를 사용하려고 하면 입력이 완료되면 오류 메시지만 표시됩니다. (참고: 이 절차가 안정적으로 작동하지 않았습니다.포스트그레스6.5 이전 버전이지만 이제 권장되는 작업 방법입니다.)

NEGATOR

NEGATOR 절이 제공되면 해당 연산자의 이름을 지정합니다. 정의되는 연산자의 부정자입니다. 우리는 연산자 A가 둘 다 부울 결과를 반환하고 (x A y)는 가능한 모든 입력 x,y에 대해 NOT(x B y)와 같습니다. B는 또한 A의 부정자입니다. 예를 들어 '<' 및 '='는 대부분의 데이터 유형에 대한 부정자 쌍. 연산자는 결코 유효할 수 없습니다. 그 자신의 부정자가 되십시오.

COMMUTATOR와 달리 단항 젠 토토 쌍은 유효할 수 있습니다. 서로의 부정자로 표시됩니다. 이는 (A x)가 NOT과 같음을 의미합니다. (B x) 모든 x에 대해 또는 오른쪽 단항 젠 토토에 해당합니다.

연산자의 부정자는 왼쪽 및/또는 오른쪽이 동일해야 합니다 COMMUTATOR와 마찬가지로 인수 유형을 연산자 자체로 지정합니다. NEGATOR 절에는 연산자 이름만 지정하면 됩니다.

NEGATOR 제공은 이후 쿼리 최적화 프로그램에 매우 도움이 됩니다. NOT (x = y)와 같은 표현식을 x로 단순화할 수 있습니다. < 야. 이 문제는 생각보다 자주 발생합니다. 왜냐하면 다른 재배열의 결과로 NOT이 삽입될 수 있습니다.

부정 젠 토토 쌍은 동일한 방법을 사용하여 정의할 수 있습니다 위에서 정류자 쌍에 대해 설명했습니다.

제한

RESTRICT 절이 제공되면 제한사항의 이름을 지정합니다. 연산자에 대한 선택성 추정 함수(이것은 연산자 이름이 아닌 함수 이름). RESTRICT 절은 오직 부울을 반환하는 이항 연산자에 대한 의미입니다. 뒤에 숨은 아이디어 제한 선택성 추정기는 테이블의 행은 WHERE 절 조건을 충족합니다. 양식

필드 OP 상수
현재 연산자 및 특정 상수 값에 대해. 이는 행 수에 대한 아이디어를 제공하여 최적화 프로그램을 지원합니다. 이 형식의 WHERE 절에 의해 제거됩니다. (뭐.. 상수가 왼쪽에 있으면 어떤 일이 발생하는지 궁금할 것입니다. 글쎄, 이것이 COMMUTATOR의 목적 중 하나입니다...)

새로운 제한 선택성 추정 함수를 작성하는 것은 멀었습니다 이 장의 범위를 벗어나지만 다행히도 일반적으로 다음을 수행할 수 있습니다. 많은 경우에 대해 시스템의 표준 추정기 중 하나를 사용하십시오. 자신의 운영자. 다음은 표준 제한 추정기입니다.

eqsel for =
        <에 대한 neqsel
        < 또는 <=에 대한 scalarltsel
         또는 =에 대한 scalargtsel
이것이 카테고리라는 것이 조금 이상해 보일 수도 있지만, 당신이 그것에 대해 생각한다면 그것은 의미가 있습니다. '='는 일반적으로 허용됩니다. 테이블에 있는 행의 작은 부분만; '<'는 일반적으로 작은 부분만 거부합니다. '<'는 주어진 상수가 어디에 속하는지에 따라 달라지는 분수 해당 테이블 열의 값 범위(이런 일이 발생하면 VACUUM ANALYZE에 의해 수집되어 다음 사용자에게 제공되는 정보입니다. 선택성 추정기). '<='는 약간 더 큰 크기를 허용합니다. 동일한 비교 상수에 대해 '<'보다 분수가 있지만 구별할 가치가 없을 만큼 가깝습니다. 특히 우리는 어쨌든 대략적인 추측보다 더 나은 결과를 얻을 가능성은 없습니다. 비슷한 말 '' 및 '='에 적용됩니다.

eqsel 또는 neqsel을 사용하면 자주 벗어날 수 있습니다. 선택성이 매우 높거나 매우 낮은 젠 토토의 경우 그것들은 실제로 평등도 불평등도 아닙니다. 예를 들어, 근사 평등 기하학 젠 토토는 eqsel을 사용합니다. 일반적으로 작은 부분에만 일치한다고 가정합니다. 테이블의 항목입니다.

비교를 위해 scalarltsel 및 scalargtsel을 사용할 수 있습니다. 다음으로 변환할 수 있는 합리적인 수단이 있는 데이터 유형 범위 비교를 위한 숫자형 스칼라. 가능하다면 데이터 유형은 Convert_to_scalar() 루틴이 이해하는 유형으로 src/백엔드/utils/adt/selfuncs.c. (결국 이 루틴은 열을 통해 식별되는 데이터 유형별 함수로 대체됩니다. pg_type 테이블의 하지만 아직 그런 일은 일어나지 않았습니다.) 그렇지 않은 경우 이렇게 하면 모든 것이 여전히 작동하지만 최적화 프로그램의 추정치는 그다지 좋지는 않을 것입니다.

다음을 위해 설계된 추가 선택 기능이 있습니다. src/backend/utils/adt/geo_selfuncs.c의 기하학적 연산자: Areasel, positionel 및 contsel. 이 글을 쓰는 시점에서 이것들은 단지 스텁이지만 사용하고 싶을 수도 있습니다(또는 개선하는 것이 더 좋습니다). 어쨌든.

가입

JOIN 절이 제공되면 조인 선택성의 이름을 지정합니다 연산자에 대한 추정 함수(이것은 함수입니다. 이름이 아닌 운영자 이름). JOIN 절은 다음 경우에만 의미가 있습니다. 부울을 반환하는 이진 연산자. 조인의 기본 아이디어 선택성 추정기는 행의 몇 부분을 추측하는 것입니다. 테이블 쌍은 WHERE 절 조건을 만족합니다. 양식

table1.field1 OP table2.field2
현재 연산자에 대한 것입니다. RESTRICT 절과 마찬가지로 이는 이를 파악함으로써 옵티마이저가 매우 실질적으로 도움을 줍니다. 여러 가능한 조인 시퀀스 중 어느 것이 최소한의 일.

이전과 마찬가지로 이 장에서는 방법을 설명하지 않습니다. 조인 선택성 추정 함수를 작성하지만 단지 제안만 할 것입니다. 다음과 같은 경우 표준 추정기 중 하나를 사용합니다. 해당:

eqjoinsel for =
        <에 대한 neqjoinsel
        < 또는 <=에 대한 scalarltjoinsel
         또는 =에 대한 scalargtjoinsel
        2D 영역 기반 비교를 위한 AreaJoinsel
        2D 위치 기반 비교를 위한 positionjoinsel
        2D 포함 기반 비교를 위한 contjoinsel

해시

HASHES 절이 있는 경우 시스템에 다음이 허용됨을 알려줍니다. 이 연산자를 기반으로 하는 조인에는 해시 조인 방법을 사용합니다. 해시 부울을 반환하는 이진 연산자에만 의미가 있으며 연산자가 일부 데이터에 대해 평등을 갖는 것이 더 나을 것을 연습하십시오. 유형.

해시 조인의 기본 가정은 조인 연산자가 해시된 왼쪽 및 오른쪽 값 쌍에 대해서만 TRUE를 반환할 수 있습니다. 동일한 해시 코드로. 두 값이 서로 다른 해시에 입력되는 경우 버킷의 경우 조인은 암시적으로 버킷을 전혀 비교하지 않습니다. 조인 연산자의 결과가 FALSE여야 한다고 가정합니다. 그래서 그렇지 않은 연산자에 대해 HASHES를 지정하는 것은 결코 의미가 없습니다. 평등을 나타냅니다.

사실 논리적 평등도 충분하지 않습니다. 는 연산자는 순수한 비트 동등성을 더 잘 표현해야 합니다. 해시 함수는 메모리 표현에서 계산됩니다. 비트가 의미하는 것과 관계없이 값을 반환합니다. 예를 들어, 평등 시간 간격은 비트 단위 평등이 아닙니다. 간격 평등 연산자는 두 시간 간격이 동일한 경우 두 시간 간격이 동일한 것으로 간주합니다. 끝점이 동일한지 여부에 관계없이 기간입니다. 이게 뭐야? 이는 간격 필드 사이에 "="를 사용하는 조인이 다음을 생성한다는 것을 의미합니다. 해시 조인으로 구현된 경우와 구현된 경우의 결과가 다릅니다. 다른 방법으로는, 쌍의 상당 부분이 일치 항목은 다른 값으로 해시되며 절대 비교되지 않습니다. 해시 조인. 그러나 옵티마이저가 다른 종류를 사용하기로 선택한 경우 조인에서 항등 연산자가 말하는 모든 쌍은 동일합니다. 발견될 것이다. 우리는 그런 불일치를 원하지 않습니다. 간격 동일성을 해시 가능으로 표시하지 마십시오.

해시 조인을 수행하는 시스템 의존적인 방법도 있습니다. 옳은 일을 하지 못합니다. 예를 들어, 데이터 유형이 흥미롭지 않은 패드 비트가 있을 수 있는 구조이므로 안전하지 않습니다. 같음 연산자 HASHES를 표시합니다. (아마도 당신이 쓰지 않는 한 사용되지 않은 비트가 항상 있는지 확인하기 위해 다른 연산자 0.) 또 다른 예는 FLOAT 데이터 유형이 안전하지 않다는 것입니다. 해시 조인. IEEE 부동 소수점 표준을 충족하는 시스템에서는 마이너스 0과 플러스 0은 다른 값입니다(다른 비트 패턴) 그러나 동일함을 비교하기 위해 정의됩니다. 그래서 플로트라면 평등은 HASHES로 표시되었으며 마이너스 0과 플러스 0은 아마도 해시 조인과 일치하지 않을 수도 있지만 다른 가입 프로세스와 일치합니다.

결론은 HASHES를 다음 용도로만 사용해야 한다는 것입니다. 다음에 의해 구현되거나 구현될 수 있는 항등 연산자 memcmp().

SORT1 및 정렬2

SORT 절이 있는 경우 시스템에 이를 알립니다. 다음을 기반으로 하는 조인에 대해 병합 조인 방법을 사용하는 것이 허용됩니다. 현재 운영자. 둘 중 하나가 있으면 둘 다 지정해야 합니다. 현재 연산자는 일부 데이터 유형 쌍에 대해 동일해야 하며 SORT1 및 SORT2 절은 순서 연산자의 이름을 지정합니다('<' 연산자)를 각각 왼쪽 및 오른쪽 데이터 유형에 사용합니다.

병합 조인은 왼쪽과 오른쪽 정렬 아이디어를 기반으로 합니다. 오른쪽 테이블을 순서대로 정렬한 다음 병렬로 스캔합니다. 그래서, 두 데이터 유형 모두 완전히 정렬될 수 있어야 하며 조인 연산자는 값 쌍에 대해서만 성공할 수 있는 연산자여야 합니다. 정렬 순서에서 "같은 위치"에 해당합니다. 실제로는 이 이는 조인 연산자가 동등하게 동작해야 함을 의미합니다. 하지만 달리 왼쪽 및 오른쪽 데이터 유형이 더 나은 해시 조인 동일(또는 적어도 비트 단위로 동일)하면 병합 조인이 가능합니다. 논리적으로 호환되는 두 가지 서로 다른 데이터 유형입니다. 예를 들어, int2-versus-int4 동등 연산자는 다음과 같습니다. 병합 가능. 두 가지를 모두 가져오는 정렬 연산자만 필요합니다. 데이터 유형을 논리적으로 호환되는 시퀀스로 변환합니다.

병합 정렬 연산자를 지정할 때 현재 연산자와 참조된 두 연산자 모두 부울을 반환해야 합니다. SORT1 연산자 현재 연산자의 왼쪽과 동일한 입력 데이터 유형이 모두 있어야 합니다. 인수 유형이며 SORT2 연산자에는 두 입력이 모두 있어야 합니다. 현재 연산자의 오른쪽 인수 유형과 동일한 데이터 유형. ( COMMUTATOR 및 NEGATOR를 사용하면 연산자 이름이 다음과 같습니다. 운영자를 지정하는 것으로 충분하며 시스템은 다음을 수행할 수 있습니다. 동등성을 정의한 경우 더미 연산자 항목 다른 연산자보다 먼저 연산자를 사용하세요.)

실제로는 '='에 대해서만 SORT 절을 작성해야 합니다. 젠 토토이며, 참조된 두 젠 토토의 이름은 항상 지정되어야 합니다. '<'. 다른 이름의 젠 토토와 병합 조인을 사용하려고 합니다. 우리가 나중에 보게 될 이유 때문에 절망적인 혼란을 초래할 것입니다. 순간.

표시한 연산자에는 추가 제한사항이 있습니다. 병합 가능. 이러한 제한 사항은 현재 확인되지 않습니다. CREATE OPERATOR, 그러나 병합 조인이 있는 경우 런타임 시 실패할 수 있음 사실이 아닙니다:

  • 병합 결합 가능 등호 젠 토토에는 정류자가 있어야 합니다. (두 데이터 유형이 동일하거나 관련된 경우 자체) 서로 다른 경우 항등 젠 토토).

  • '<' 및 '' 순서 젠 토토가 있어야 합니다. mergejoinable과 동일한 왼쪽 및 오른쪽 입력 데이터 유형 운영자 그 자체. 이들 젠 토토반드시'<' 및 ''로 명명됩니다. 너에겐 선택의 여지가 없어 문제는 이를 명시하는 조항이 없기 때문이다. 명시적으로. 왼쪽 및 오른쪽 데이터 유형이 다음과 같은 경우 다릅니다. 이 연산자 중 어느 것도 동일하지 않습니다. 정렬 연산자. 하지만 데이터 값을 순서대로 정렬하는 것이 좋습니다. SORT 연산자와 호환되지 않으면 mergejoin이 실패합니다. 일.