설명
#postgresqla 고안쿼리 토토 핫각 쿼리마다 수신합니다. 쿼리 구조와 데이터의 속성에 맞는 올바른 토토 핫을 선택하는 것은 좋은 성능에 절대적으로 중요하므로 시스템에는 복잡한 것이 포함됩니다플래너좋은 계획을 선택하려고합니다. 를 토토 핫할 수 있습니다.설명
명령은 플래너가 쿼리에 대해 어떤 쿼리 토토 핫을 작성하는지 확인하십시오. 계획 읽기는 마스터하는 데 약간의 경험이 필요한 예술이지만이 섹션은 기본 사항을 다루려고 시도합니다.
이 섹션의 예는 a 후 회귀 테스트 데이터베이스에서 그려집니다.진공 분석
10851_11030분석
의 통계는 정확한 것이 아닌 임의의 샘플이며 토토 핫이 본질적으로 다소 플랫폼 의존적이기 때문에
예제 토토 핫설명
의 기본값“텍스트”출력 형식은 인간이 읽기에 편리하고 편리합니다. 피드를 원한다면설명
의 추가 분석을 위해 프로그램에 출력하면 기계로 읽을 수있는 출력 형식 중 하나를 사용해야합니다.
설명
기본#쿼리 토토 핫의 구조는의 나무입니다.토토 핫 노드. 트리의 하단 레벨의 노드는 스캔 노드입니다. 테이블에서 원시 행을 반환합니다. 다양한 테이블 액세스 방법에 대한 다양한 유형의 스캔 노드가 있습니다 : 순차적 스캔, 인덱스 스캔 및 비트 맵 인덱스 스캔. 와 같은 비 테이블 행 소스도 있습니다.값
조항 및 세트 퇴행 함수From
, 자체 스캔 노드 유형이 있습니다. If the query requires joining, aggregation, sorting, or other operations on the raw rows, then there will be additional nodes above the scan nodes to perform these operations. 다시 말하지만, 이러한 작업을 수행하는 가능한 방법은 하나 이상 있으므로 다른 노드 유형도 여기에 나타날 수 있습니다. 의 출력설명
플랜 트리의 각 노드마다 하나의 줄이있어 기본 노드 유형과 토토 핫이 해당 토토 핫 노드의 실행을 위해 만든 토토 핫 추정치를 보여줍니다. 노드의 추가 특성을 보여주기 위해 노드의 요약 라인에서 들여 쓰기 된 추가 선이 나타날 수 있습니다. 첫 번째 줄 (최상위 노드의 요약 라인)에는 계획의 총 실행 토토 핫이 추정됩니다. 플래너가 최소화하려는 것은이 숫자입니다.
여기에 출력이 어떻게 보이는지 보여주기 위해 사소한 예가 있습니다.
설명을 설명하십시오 * Tenk1에서; 쿼리 토토 핫 ---------------------------------------------------------------------------------- Tenk1의 Seq 스캔 (토토 핫 = 0.00..445.00 행 = 10000 너비 = 244)
이 쿼리가 없기 때문에여기서
절, 절, 테이블의 모든 행을 스캔해야하므로 플래너는 간단한 순차적 스캔 계획을 사용하도록 선택했습니다. 괄호 안에 인용 된 숫자는 (왼쪽에서 오른쪽으로) :
예상 시작 토토 핫. 이것은 출력 단계가 시작되기 전에 소비 된 시간 (예 : 정렬 노드에서 정렬을 수행 할 시간입니다.
총 토토 핫. 이는 토토 핫 노드가 완성 된 것으로 간주되며, 즉 사용 가능한 모든 행이 검색된다는 가정에 따라 언급됩니다. 실제로 노드의 상위 노드는 사용 가능한 모든 행을 읽지 않는 것이 멈출 수 있습니다 (참조Limit
아래 예).
이 토토 핫 노드에 의해 추정 된 행 출력 수. 다시, 노드는 완료로 실행되는 것으로 가정합니다.
이 토토 핫 노드 (바이트)에 의해 출력의 평균 평균 폭
토토 핫은 플래너의 토토 핫 매개 변수에 의해 결정된 임의 단위로 측정됩니다 (참조섹션 19.7.2). 전통적인 관행은 디스크 페이지 가져 오기 단위의 토토 핫을 측정하는 것입니다. 즉,seq_page_cost전통적으로 설정되어1.0
다른 토토 핫 매개 변수는 이에 비해 설정됩니다. 이 섹션의 예제는 기본 토토 핫 매개 변수로 실행됩니다.
상위 수준의 노드 토토 핫에는 모든 하위 노드의 토토 핫이 포함되어 있음을 이해하는 것이 중요합니다. 토토 핫은 플래너가 관심을 갖는 것만 반영한다는 것을 인식하는 것도 중요합니다. 특히, 토토 핫은 출력 값을 텍스트 형식으로 변환하거나 클라이언트로 전송하는 데 소요되는 시간을 고려하지 않으며, 이는 실제 경과 시간에 중요한 요소가 될 수 있습니다. 그러나 플래너는 계획을 변경하여 변경할 수 없기 때문에 이러한 토토 핫을 무시합니다. (모든 정확한 계획은 동일한 행 세트를 출력합니다. 우리는 신뢰합니다.)
the행
값은 토토 핫 노드에 의해 처리되거나 스캔 된 행의 수가 아니라 노드에 의해 방출되는 숫자이기 때문에 약간 까다 롭습니다. 이것은 종종 스캔 한 숫자보다 적습니다.여기서
-노드에 적용되는 클레스트 조건. 이상적으로 최상위 행 추정치는 쿼리에 의해 실제로 반환, 업데이트 또는 삭제 된 행의 수에 근사합니다.
예제로 돌아 가기 :
설명 *에서 10에서 선택하십시오. 쿼리 토토 핫 ---------------------------------------------------------------------------------- Tenk1의 Seq 스캔 (토토 핫 = 0.00..445.00 행 = 10000 너비 = 244)
이 숫자는 매우 간단하게 파생됩니다. 그렇다면 :
relname = 'tenk1'; pg_class에서 reelpages, reltuples를 선택하십시오.
당신은 그것을 알게 될 것입니다Tenk1
345 개의 디스크 페이지와 10000 행이 있습니다. 예상 토토 핫은 (디스크 페이지 읽기 *로 계산됩니다.SEQ_PAGE_COST) + (줄 스캔 *CPU_TUPLE_COST). 기본적으로seq_page_cost
is 1.0 andCPU_TUPLE_COST
는 0.01이므로 추정 토토 핫은 (345 * 1.0) + (10000 * 0.01) = 445입니다.
이제 쿼리를 수정하여 A여기서
조건 :
Tenk1에서 선택 *을 설명하십시오. 쿼리 토토 핫 ------------------------------------------------------------------- Tenk1의 Seq 스캔 (토토 핫 = 0.00..470.00 행 = 7000 너비 = 244) 필터 : (고유 한 <7000)
설명
출력 표시여기서
조항이 A로 적용되고 있습니다“필터”SEQ 스캔 토토 핫 노드에 첨부 된 조건. 이는 토토 핫 노드가 스캔 한 각 행의 조건을 확인하고 조건을 전달하는 것만 출력 함을 의미합니다. 출력 행의 추정치는 때문에 감소했습니다.여기서
절. 그러나 스캔은 여전히 10000 행을 모두 방문해야하므로 토토 핫이 줄어들지 않았습니다. 사실 그것은 조금 올라갔습니다 (10000 *cpu_operator_cost, 정확히) 추가 CPU 시간을 반영하려면여기서
조건.
이 쿼리를 선택할 실제 행 수는 7000이지만행
추정치는 대략적인 것입니다. 이 실험을 복제하려고하면 약간 다른 견적을 얻을 수 있습니다. 또한 각각 변경 될 수 있습니다분석
명령, 통계가 생성 된 통계분석
테이블의 무작위 샘플에서 가져 왔습니다.
이제 조건을보다 제한적으로 만들자 :
10 <100에서 tenk1에서 선택 *을 선택하십시오. 쿼리 토토 핫 ------------------------------------------------------------------------------------- Tenk1의 비트 맵 힙 스캔 (토토 핫 = 5.06..224.98 행 = 100 너비 = 244) COND를 다시 확인하십시오 : (고유 1 <100) - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..5.04 행 = 100 너비 = 0) 색인 조건 : (고유 1 <100)
여기서 플래너는 2 단계 계획을 사용하기로 결정했습니다. 아동 토토 핫 노드는 색인을 방문하여 인덱스 조건과 일치하는 행의 위치를 찾은 다음 상단 토토 핫 노드는 실제로 테이블 자체에서 해당 행을 가져옵니다. 별도의 행을 따로 가져 오는 것은 순차적으로 읽는 것보다 훨씬 비싸지 만 테이블의 모든 페이지를 방문 할 필요는 없기 때문에 여전히 순차적 스캔보다 저렴합니다. (두 개의 계획 수준을 사용하는 이유는 상단 토토 핫 노드가 독해하기 전에 인덱스로 식별 된 행 위치를 물리적 순서로 정렬하여 별도의 페치 토토 핫을 최소화하기 때문입니다.“비트 맵”노드 이름에 언급 된 것은 정렬을 수행하는 메커니즘입니다.)
이제 다른 조건을 추가합시다어디
절 :
tenk1에서 선택 *을 선택하십시오. 쿼리 토토 핫 ------------------------------------------------------------------------------------- Tenk1의 비트 맵 힙 스캔 (토토 핫 = 5.04..225.20 줄 = 1 너비 = 244) COND를 다시 확인하십시오 : (고유 1 <100) 필터 : (stringu1 = 'xxx':: name) - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..5.04 행 = 100 너비 = 0) 색인 조건 : (고유 1 <100)
추가 조건StringU1 = 'xxx'
출력 행 카운트 추정치를 줄이지 만 여전히 동일한 행 세트를 방문해야하기 때문에 토토 핫은 아닙니다. 그게이기 때문입니다.StringU1
조항은 색인 조건으로 적용 할 수 없습니다.이 인덱스는에만 있으므로고유 1
열. 대신 인덱스를 사용하여 검색된 행의 필터로 적용됩니다. 따라서 토토 핫은 실제로이 추가 점검을 반영하기 위해 약간 증가했습니다.
경우에 따라 플래너는 a를 선호합니다.“단순”색인 스캔 토토 핫 :
설명을 선택하십시오. 쿼리 토토 핫 ---------------------------------------------------------------------------------- Tenk1에서 Tenk1_unique1을 사용한 인덱스 스캔 (토토 핫 = 0.29..8.30 행 = 1 너비 = 244) 색인 조건 : (고유 1 = 42)
이 유형의 계획에서 테이블 행은 색인 순서로 가져 오므로 읽는 데 더 비싸지 만 행 위치를 정렬하는 데 드는 추가 비용은 그만한 가치가 없습니다. 단일 행만 가져 오는 쿼리에 대한이 계획 유형을 가장 자주 볼 수 있습니다. 또한 종종에 토토 핫됩니다.주문
인덱스 순서와 일치하는 조건은 추가 분류 단계가 필요하지 않기 때문에주문 by
. 이 예에서는 추가Order by Oright1
색인이 이미 요청 된 주문을 제공하기 때문에 동일한 계획을 사용합니다.
플래너는 an을 구현할 수 있습니다.주문 by
여러 가지 방법으로 조항. 위의 예는 그러한 순서 조항이 암시 적으로 구현 될 수 있음을 보여준다. 플래너는 또한 명백한 것을 추가 할 수 있습니다Sort
단계 :
Select * from Tenk1 Order에 의해 select *; 쿼리 토토 핫 -------------------------------------------------------------------------------- 정렬 (토토 핫 = 1109.39..1134.39 행 = 10000 너비 = 244) 정렬 키 : 고유 한 - tenk1에서 seq 스캔 (토토 핫 = 0.00..445.00 행 = 10000 너비 = 244)
계획의 일부가 필요한 정렬 키의 접두사에 대한 주문을 보장하면 플래너는 대신를 사용하기로 결정할 수 있습니다.증분 정렬
단계 :
설명 *에서 * Tenk1 Order에서 100 개, 제한 100을 선택하십시오. 쿼리 토토 핫 ---------------------------------------------------------------------------------------------------------- 한계 (토토 핫 = 19.35..39.49 행 = 100 너비 = 244) - 증분 정렬 (토토 핫 = 19.35..2033.39 행 = 10000 너비 = 244) 정렬 키 : 백, 10 분리 된 키 : 백 - tenk1에서 tenk1_hundred를 사용한 인덱스 스캔 (토토 핫 = 0.29..1574.20 행 = 10000 너비 = 244)
일반 정렬과 비교하여 전체 결과 세트가 정렬되기 전에 튜플을 점차적으로 정렬 할 수 있으므로 특히를 최적화 할 수 있습니다.Limit
쿼리. 또한 메모리 토토 핫량과 디스크에 정렬을 유출 할 가능성을 줄일 수 있지만 결과를 여러 정렬 배치로 분할하는 데 드는 오버 헤드가 증가하는 비용이 발생합니다..
참조 된 여러 열에 별도의 인덱스가있는 경우여기서
, 플래너는 인덱스의 및 또는 또는 또는 조합을 사용하도록 선택할 수 있습니다 :
10 <100 및 고유 2 9000에서 10에서 선택 *을 선택하십시오. 쿼리 토토 핫 --------------------------------------------------------------------------------------------- Tenk1의 비트 맵 힙 스캔 (토토 핫 = 25.07....60.11 행 = 10 너비 = 244) COND를 다시 확인하십시오 : ((고유 1 <100) 및 (고유 2 9000)) - bitmapand (토토 핫 = 25.07..25.07 행 = 10 너비 = 0) - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..5.04 행 = 100 너비 = 0) 색인 조건 : (고유 1 <100) - tenk1_unique2의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..19.78 행 = 999 너비 = 0) 색인 조건 : (고유 2 9000)
그러나 이것은 두 인덱스를 모두 방문해야하므로 하나의 색인 만 사용하고 다른 조건을 필터로 처리하는 것과 비교할 때 반드시 승리는 아닙니다. 당신이 관련된 범위를 변화 시키면 그에 따라 계획이 변경 될 것입니다.
다음은의 효과를 보여주는 예입니다.Limit
:
10 <100 및 고유 한 LIMIT 2에서 10 <100 및 고유 한 제한을 선택하십시오. 쿼리 토토 핫 --------------------------------------------------------------------------------------------- 한계 (토토 핫 = 0.29..14.28 행 = 2 너비 = 244) - tenk1에서 tenk1_unique2를 사용한 색인 스캔 (토토 핫 = 0.29..70.27 행 = 10 너비 = 244) 색인 조건 : (고유 2 9000) 필터 : (고유 한 <100)
이것은 위와 동일한 쿼리이지만 A를 추가했습니다.Limit
모든 행을 검색 할 필요는 없으며 플래너가해야 할 일에 대한 마음이 바뀌 었습니다. 인덱스 스캔 노드의 총 토토 핫과 행 카운트는 마치 완료된 것처럼 표시됩니다. 그러나 해당 행의 5 분의 1 만 검색 한 후 한도 노드가 중지 될 것으로 예상되므로 총 토토 핫은 5 분의 1에 불과하며 실제 추정 토토 핫입니다. 이 계획은 한계가 비트 맵 스캔의 시작 토토 핫을 지불하는 것을 피할 수 없기 때문에 이전 계획에 한계 노드를 추가하는 것보다 선호됩니다. 따라서 총 토토 핫은 해당 접근법의 25 개 이상의 유닛이 될 것입니다..
우리가 논의한 열을 토토 핫하여 두 개의 테이블을 결합 해 보자.
선택 선택 * TENK1 T1, TENK2 T2로부터 여기서 t1.unique1 <10 및 t1.unique2 = t2.unique2; 쿼리 토토 핫 ------------------------------------------------------------------------------------------------------ 중첩 루프 (토토 핫 = 4.65..118.50 행 = 10 너비 = 488) - tenk1 t1의 비트 맵 힙 스캔 (토토 핫 = 4.36..39.38 행 = 10 너비 = 244) COND를 다시 확인하십시오 : (고유 1 <10) - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..4.36 행 = 10 너비 = 0) 색인 조건 : (고유 1 <10) - tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔 (토토 핫 = 0.29..7.90 행 = 1 너비 = 244) 색인 조건 : (고유 2 = t1.unique2)
이 토토 핫에는 입력 또는 어린이로 두 개의 테이블 스캔이있는 중첩 루프 조인 노드가 있습니다. 노드 요약 라인의 압입은 토토 핫 트리 구조를 반영합니다. 가입은 첫 번째, 또는“외부”, 자식은 이전에 본 것과 비슷한 비트 맵 스캔입니다. 토토 핫과 행 수는 우리가 얻은 것과 동일합니다SELECT ... WHEREINED 1 <10
우리가 신청하고 있기 때문에여기서
절고유 한 <10
해당 노드에서. 그만큼t1.unique2 = t2.unique2
절은 아직 관련이 없으므로 외부 스캔의 행 수에 영향을 미치지 않습니다. 중첩 루프 조인 노드가 두 번째로 실행됩니다.“내부”외부 아동으로부터 얻은 각 행에 대해 한 번 자식. 현재 외부 행의 열 값은 내부 스캔에 연결할 수 있습니다. 여기,t1.unique2
외부 행의 값을 사용할 수 있으므로, 우리는 단순한 것으로 위에서 본 것과 유사한 계획과 토토 핫을 얻습니다선택 ... 여기서 t2.unique2 =
케이스. (추정 토토 핫은 실제로 위에서 보았던 것보다 약간 낮습니다. 반복 된 인덱스 스캔에서 발생할 것으로 예상되는 캐싱의 결과Constant
T2
.) 루프 노드의 토토 핫은 외부 스캔 토토 핫과 각 외부 행에 대한 내부 스캔 (10 * 7.90, 여기)에 대한 한 번의 반복과 조인 처리 시간에 대한 약간의 CPU 시간을 기준으로 설정됩니다..
이 예에서 조인의 출력 행 카운트는 두 스캔 행 카운트의 제품과 동일하지만 추가가있을 수 있기 때문에 모든 경우에 해당되는 것은 아닙니다여기서
두 테이블을 모두 언급하는 조항과 입력 스캔이 아닌 결합 지점에서만 적용 할 수 있습니다. 예는 다음과 같습니다.
선택 선택 * TENK1 T1, TENK2 T2로부터 여기서 t1.unique1 <10 및 t2.unique2 <10 및 t1.hundred <t2.hundred; 쿼리 토토 핫 ------------------------------------------------------------------------------------------------------- 중첩 루프 (토토 핫 = 4.65..49.36 줄 = 33 너비 = 488) 가입 필터 : (T1. Hundred <t2.hundred) - tenk1 t1의 비트 맵 힙 스캔 (토토 핫 = 4.36..39.38 행 = 10 너비 = 244) COND를 다시 확인하십시오 : (고유 1 <10) - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..4.36 행 = 10 너비 = 0) 색인 조건 : (고유 1 <10) - 구체화 (토토 핫 = 0.29..8.51 행 = 10 너비 = 244) - tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔 (토토 핫 = 0.29..8.46 행 = 10 너비 = 244) 색인 조건 : (고유 2 <10)
조건T1. HUNDRED <T2.HUNDRED
테스트 할 수 없습니다Tenk2_unique2
index이므로 결합 노드에 적용됩니다. 이렇게하면 결합 노드의 추정 출력 행 카운트가 줄어들지 만 입력 스캔 중 하나는 변경되지 않습니다.
여기서 플래너가 선택한 것을 주목하십시오“구체화”구체화 된 토토 핫 노드를 꼭대기에 넣음으로써 조인의 내부 관계. 이것은를 의미합니다.T2
Nested-Loop Join Node가 외부 관계에서 각 행에 대해 한 번 해당 데이터를 10 번 읽어야하더라도 인덱스 스캔이 한 번만 수행됩니다. 구체화 노드는 읽기에 따라 메모리에 데이터를 저장 한 다음 각 후속 패스에서 메모리에서 데이터를 반환합니다..
OUTER 조인을 다루는 경우 두 가지 모두가있는 토토 핫 노드가 표시 될 수 있습니다.“결합 필터”및 일반“필터”첨부 된 조건. 결합 필터 조건은 OUTER JOIN의에서 나옵니다.on
조항, 따라서 결합 필터 조건에 실패하는 행은 여전히 널 확장 행로 방출 될 수 있습니다. 그러나 일반 필터 조건은 외부 결합 규칙에 따라 적용되므로 무조건 행을 제거하기 위해 작용합니다. 내부 결합에는 이러한 유형의 필터간에 의미 적 차이가 없습니다.
쿼리의 선택성을 조금 변경하면 매우 다른 조인 토토 핫을 얻을 수 있습니다.
선택 선택 * TENK1 T1, TENK2 T2로부터 여기서 t1.unique1 <100 및 t1.unique2 = t2.unique2; 쿼리 토토 핫 -------------------------------------------------------------------------------------------------- 해시 조인 (토토 핫 = 226.23..709.73 줄 = 100 너비 = 488) 해시 조건 : (T2.Unique2 = t1.unique2) - TENK2 T2의 SEQ 스캔 (토토 핫 = 0.00..445.00 행 = 10000 너비 = 244) - 해시 (토토 핫 = 224.98..224.98 행 = 100 너비 = 244) - tenk1 t1의 비트 맵 힙 스캔 (토토 핫 = 5.06..224.98 행 = 100 너비 = 244) COND를 다시 확인하십시오 : (고유 1 <100) - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..5.04 행 = 100 너비 = 0) 색인 조건 : (고유 1 <100)
여기서, 플래너는 해시 조인을 사용하기로 선택했으며,이 테이블의 행은 메모리 내 해시 테이블에 입력되고 다른 테이블이 스캔되고 해시 테이블이 각 행과 일치하도록 프로브됩니다. 다시 들여 쓰기가 계획 구조를 어떻게 반영하는지 다시 주목하십시오. 비트 맵 스캔Tenk1
해시 테이블을 구성하는 해시 노드에 대한 입력입니다. 그런 다음 해시 결합 노드로 돌아와서 외부 아동 계획에서 행을 읽고 각각의 해시 테이블을 검색합니다..
다른 가능한 유형의 조인 유형은 여기에 설명 된 합병 조인입니다.
선택 선택 * TENK1 T1, ONEK T2로부터 여기서 t1.unique1 <100 및 t1.unique2 = t2.unique2; 쿼리 토토 핫 -------------------------------------------------------------------------------------------------- 합병 조인 (토토 핫 = 0.56..233.49 행 = 10 너비 = 488) 병합 Cond : (T1.unique2 = T2.Unique2) - tenk1 t1에서 tenk1_unique2를 사용한 인덱스 스캔 (토토 핫 = 0.29..643.28 행 = 100 너비 = 244) 필터 : (고유 한 <100) - Onek t2에서 Onek_unique2를 사용한 색인 스캔 (토토 핫 = 0.28..166.28 행 = 1000 너비 = 244)
합병 결합은 결합 키에 입력 데이터를 정렬해야합니다. 이 예에서 각 입력은 인덱스 스캔을 토토 핫하여 올바른 순서로 행을 방문하여 정렬됩니다. 그러나 순차적 스캔과 정렬도 토토 핫할 수 있습니다. (인덱스 스캔에 필요한 비 순차 디스크 액세스로 인해 많은 행을 정렬하기위한 인덱스 스캔을 종종 순차적으로 스캔합니다.)
변형 계획을 보는 한 가지 방법은 플래너가 가장 저렴하다고 생각한 전략을 무시하고에 설명 된 깃발을 사용하여 가장 저렴한 전략을 무시하는 것입니다.섹션 19.7.1. (이것은 조잡한 도구이지만 유용합니다. 참조PostgreSQL : 문서 : 17 : 14.3. 명백한 무지개 토토 조항으로 플래너 제어.) 예를 들어, Merge 조인이 이전 예제의 가장 좋은 조인 유형이라는 것이 확신이없는 경우
set enable_mergejoin = off; 선택 * * TENK1 T1, ONEK T2로부터 여기서 t1.unique1 <100 및 t1.unique2 = t2.unique2; 쿼리 토토 핫 -------------------------------------------------------------------------------------------------- 해시 조인 (토토 핫 = 226.23..344.08 행 = 10 너비 = 488) 해시 조건 : (T2.Unique2 = t1.unique2) - Onek t2의 SEQ 스캔 (토토 핫 = 0.00..114.00 행 = 1000 너비 = 244) - 해시 (토토 핫 = 224.98..224.98 행 = 100 너비 = 244) - tenk1 t1의 비트 맵 힙 스캔 (토토 핫 = 5.06..224.98 행 = 100 너비 = 244) COND를 다시 확인하십시오 : (고유 1 <100) - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..5.04 행 = 100 너비 = 0) 색인 조건 : (고유 1 <100)
플래너는 해시 조인 이이 사례에 대한 합병 조인보다 거의 50% 더 비싸다고 생각한다는 것을 보여줍니다. 물론 다음 질문은 그것이 옳은지 여부입니다. 우리는 그것을 사용하는 것을 조사 할 수 있습니다분석 설명
, 논의 된대로아래.
일부 쿼리 토토 핫이 포함됩니다서브 플랜.select
원래 쿼리에 있습니다. 이러한 쿼리는 때때로 일반적인 조인 토토 핫으로 변환 될 수 있지만, 그렇지 않으면 다음과 같은 토토 핫을 얻습니다.
verbose select 고유 한 설명 Tenk1 t에서 여기서 t.ten <all (Onek o에서 o.ten을 선택하십시오. 여기서 o.four = t.four); 쿼리 토토 핫 ----------------------------------------------------------------------------------- public.tenk1 t에서 seq scan (cost = 0.00..586095.00 행 = 5000 너비 = 4) 출력 : T.unique1 필터 : (모두 (T.ten <(하위 플랜 1) .col1)))) 하위 비행 1 - public.onek o에서 seq scan (cost = 0.00..116.50 줄 = 250 너비 = 4) 출력 : O.Ten 필터 : (O.four = T.four)
This rather artificial example serves to illustrate a couple of points: values from the outer plan level can be passed down into a subplan (here,T.four
가 전달됨) 및 하위 선택의 결과는 외부 계획에서 사용할 수 있습니다. 그 결과 값은에 의해 표시됩니다.설명
같은 표기법(
.subplan_name
) .coln
n
'sub의 출력 열select
.
위의 예에서all
운영자는 외부 쿼리의 각 행에 대해 하위 비행기를 다시 실행합니다 (높은 추정 토토 핫을 차지). 일부 쿼리는 A를 사용할 수 있습니다.해시 하위 플랜피하려면 :
선택 선택 * Tenk1 t에서 여기서 t.unique1이 아닌 곳 (Onek O에서 O.unique1을 선택); 쿼리 토토 핫 ----------------------------------------------------------------------------------------------- Tenk1 t에서 SEQ 스캔 (토토 핫 = 61.77....531.77 행 = 5000 너비 = 244) 필터 : (a nont (any any1 = (Hashed Subplan 1) .col1))))) 하위 비행 1 - INDEX ONEK O에서 OneK_Unique1을 사용하여 스캔합니다 (토토 핫 = 0.28..59.27 행 = 1000 너비 = 4) (4 줄)
여기에서, 하위 비행은 단일 시간으로 실행되고 출력이 메모리 해시 테이블에로드 된 다음 외부에 의해 조사됩니다any
운영자. 이것은 하위를 요구합니다.select
외부 쿼리의 변수를 참조하지 않고any
의 비교 연산자는 해싱에 적합합니다.
외부 쿼리의 변수를 참조하지 않고 하위select
둘 이상의 행을 반환 할 수 없으며 대신로 구현 될 수 있습니다.Initplan:
verbose select 고유 한 설명 tenk1 t1에서 t1.ten = (select (random () * 10) :: 정수); 쿼리 토토 핫 ------------------------------------------------------------------------ public.tenk1 t1에서의 seq 스캔 (토토 핫 = 0.02..470.02 행 = 1000 너비 = 4) 출력 : t1.unique1 필터 : (t1.ten = (initplan 1) .col1) 초대 1 - 결과 (토토 핫 = 0.00..0.02 줄 = 1 너비 = 4) 출력 : ((임의
Initplan은 외부 계획의 실행 당 한 번만 실행되며 결과는 외부 계획의 이후 행에서 재사용을 위해 저장됩니다. 그래서이 예에서random ()
한 번만 평가됩니다.t1.ten
는 무작위로 선택된 정수와 비교됩니다. 그것은 서브없이 일어날 일과는 상당히 다릅니다.select
구성.
분석 설명
39899_39902사용하여 플래너 추정치의 정확도를 확인할 수 있습니다설명
's분석
옵션. 이 옵션으로설명
실제로 쿼리를 실행 한 다음 각 토토 핫 노드 내에 축적 된 실제 행 카운트 및 실제 실행 시간을 표시하고 동일한 추정치와 동일한 추정치설명
쇼. 예를 들어, 우리는 다음과 같은 결과를 얻을 수 있습니다.
분석 선택 * TENK1 T1, TENK2 T2로부터 여기서 t1.unique1 <10 및 t1.unique2 = t2.unique2; 쿼리 토토 핫 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------. 중첩 루프 (토토 핫 = 4.65..118.50 행 = 10 너비 = 488) (실제 시간 = 0.017..0.051 행 = 10 루프 = 1) - tenk1 t1의 비트 맵 힙 스캔 (토토 핫 = 4.36..39.38 행 = 10 너비 = 244) (실제 시간 = 0.009..0.017 행 = 10 루프 = 1) COND를 다시 확인하십시오 : (고유 1 <10) 힙 블록 : 정확한 = 10 - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..4.36 행 = 10 너비 = 0) (실제 시간 = 0.004..0.004 행 = 10 루프 = 1) 색인 조건 : (고유 1 <10) - tenk2 t2에서 tenk2_unique2를 사용한 인덱스 스캔 (토토 핫 = 0.29..7.90 행 = 1 너비 = 244) (실제 시간 = 0.003..0.003 행 = 1 루프 = 10) 색인 조건 : (고유 2 = t1.unique2) 토토 핫 시간 : 0.485ms 실행 시간 : 0.073 MS
“실제 시간”값은 실시간 밀리 초에 있지만토토 핫
추정치는 임의 단위로 표현됩니다. 그래서 그들은 일치하지 않을 것입니다. 일반적으로 가장 중요한 것은 추정 행 카운트가 현실에 상당히 가까운 지 여부입니다. 이 예에서 추정치는 모두 죽었지 만 실제로는 매우 드문 일입니다.
일부 쿼리 토토 핫에서는 하위 플랜 노드를 두 번 이상 실행할 수 있습니다. 예를 들어, 내부 색인 스캔은 위의 중첩 루프 계획에서 외부 행당 한 번 실행됩니다. 그러한 경우루프
값은 노드의 총 실행 수를보고하며, 표시된 실제 시간 및 행 값은 평균 실행입니다. 이것은 토토 핫 추정치가 표시되는 방식과 비교할 수 있도록하기 위해 수행됩니다. 곱하기루프
실제로 노드에서 소비 된 총 시간을 얻는 값. 위의 예에서는 Index Scans On을 실행하는 데 총 0.030 밀리 초를 소비했습니다.Tenk2
.
경우에 따라분석
토토 핫 노드 실행 시간 및 행 카운트를 넘어서 추가 실행 통계를 보여줍니다. 예를 들어 정렬 및 해시 노드는 추가 정보를 제공합니다.
선택을 설명하십시오 * TENK1 T1, TENK2 T2로부터 여기서 t1.unique1 <100 및 t1.unique2 = t2.unique2 t1.fiveThous의 순서; 쿼리 토토 핫 -------------------------------------------------------------------------------------------------------------------------------------------- 정렬 (토토 핫 = 713.05..713.30 행 = 100 너비 = 488) (실제 시간 = 2.995..3.002 행 = 100 루프 = 1) 정렬 키 : T1. 피브 러스 정렬 방법 : QuickSort 메모리 : 74KB - 해시 조인 해시 조건 : (T2.Unique2 = t1.unique2) - tenk2 t2의 seq 스캔 (토토 핫 = 0.00..445.00 행 = 10000 너비 = 244) (실제 시간 = 0.026..1.790 행 = 100000 루프 = 1) - 해시 (토토 핫 = 224.98..224.98 행 = 100 너비 = 244) (실제 시간 = 0.476..0.477 행 = 100 루프 = 1) 버킷 : 1024 배치 : 1 메모리 사용량 : 35KB - tenk1 t1의 비트 맵 힙 스캔 (토토 핫 = 5.06..224.98 행 = 100 너비 = 244) (실제 시간 = 0.030..0.450 행 = 100 루프 = 1) COND를 다시 확인하십시오 : (고유 1 <100) 힙 블록 : 정확한 = 90 - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..5.04 행 = 100 너비 = 0) (실제 시간 = 0.013..0.013 행 = 100 루프 = 1) 색인 조건 : (고유 1 <100) 토토 핫 시간 : 0.187ms 실행 시간 : 3.036 MS
정렬 노드는 토토 핫 된 정렬 메소드 (특히 정렬이 메모리 인 또는 디스크인지) 및 필요한 메모리 또는 디스크 공간의 양을 보여줍니다. 해시 노드는 해시 버킷과 배치의 수와 해시 테이블에 토토 핫되는 피크 양의 메모리를 보여줍니다. (배치 수가 하나를 초과하면 디스크 공간 토토 핫이 포함되지만 표시되지 않습니다.)
다른 유형의 추가 정보는 필터 조건에 의해 제거 된 행의 수입니다 :
10 <7에서 10 <7; 쿼리 토토 핫 --------------------------------------------------------------------------------------------------------------------------- Tenk1의 Seq 스캔 (토토 핫 = 0.00..470.00 행 = 7000 너비 = 244) (실제 시간 = 0.030..1.995 행 = 7000 루프 = 1) 필터 : (10 <7) 필터로 제거 된 행 : 3000 토토 핫 시간 : 0.102ms 실행 시간 : 2.145 ms
이 카운트는 조인 노드에 적용되는 필터 조건에 특히 유용 할 수 있습니다. 그만큼“줄이 제거”라인은 결합 노드의 경우 적어도 하나의 스캔 한 행 또는 전위 조인 쌍이 필터 조건에 의해 거부 될 때만 나타납니다..
필터 조건과 유사한 경우“Lossy”인덱스 스캔. 예를 들어, 특정 요점을 포함하는 다각형에 대한이 검색을 고려하십시오.
polygon_tbl에서 선택 * 선택 * f1 @ 다각형 '(0.5,2.0)'; 쿼리 토토 핫 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------. polygon_tbl에서의 seq 스캔 (cost = 0.00..1.09 줄 = 1 너비 = 85) (실제 시간 = 0.023..0.023 줄 = 0 루프 = 1) 필터 : (f1 @ '((0.5,2))':: 다각형) 필터에 의해 제거 된 행 : 7 토토 핫 시간 : 0.039ms 실행 시간 : 0.033 MS
플래너는이 샘플 테이블이 인덱스 스캔으로 귀찮게하기에는 너무 작다 고 생각합니다. 따라서 필터 조건에 의해 모든 행이 거부되는 일반적인 순차적 스캔이 있습니다. 그러나 인덱스 스캔을 사용하도록 강요하면 다음을 볼 수 있습니다.
enable_seqscan을 OFF로 설정합니다. polygon_tbl에서 선택 * 선택 *을 설명하십시오. 여기서 f1 @ 다각형 '(0.5,2.0)'; 쿼리 토토 핫 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------. polygon_tbl에서 gpolygonind를 사용한 인덱스 스캔 (토토 핫 = 0.13..8.15 행 = 1 너비 = 85) (실제 시간 = 0.074..0.074 행 = 0 루프 = 1) 색인 조건 : (f1 @ '((0.5,2))':: 다각형) 인덱스 재확인으로 제거 된 행 : 1 토토 핫 시간 : 0.039ms 실행 시간 : 0.098 ms
여기서 인덱스가 하나의 후보 행을 반환 한 후 인덱스 조건의 재확인으로 거부되었음을 알 수 있습니다. 이것은 GIST 지수가이기 때문에 발생합니다.“Lossy”다각형 격리 테스트의 경우 : 실제로 대상과 겹치는 다각형으로 행을 반환 한 다음 해당 행에 대한 정확한 격리 테스트를 수행해야합니다..
설명
a버퍼
분석
더 많은 실행 시간 통계를 얻으려면 :
설명 (분석, 버퍼) 선택 * 10 <100 및 고유 2 9000; 쿼리 토토 핫 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------. Tenk1의 비트 맵 힙 스캔 (토토 핫 = 25.07....60.11 행 = 10 너비 = 244) (실제 시간 = 0.105..0.114 행 = 10 루프 = 1) COND를 다시 확인하십시오 : ((고유 1 <100) 및 (고유 2 9000)) 힙 블록 : 정확한 = 10 버퍼 : 공유 적중 = 14 읽기 = 3 - bitmapand (토토 핫 = 25.07..25.07 행 = 10 너비 = 0) (실제 시간 = 0.100..0.101 행 = 0 루프 = 1) 버퍼 : 공유 적중 = 4 읽기 = 3 - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..5.04 행 = 100 너비 = 0) (실제 시간 = 0.027..0.027 행 = 100 루프 = 1) 색인 조건 : (고유 1 <100) 버퍼 : 공유 적중 = 2 - tenk1_unique2의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..19.78 행 = 999 너비 = 0) (실제 시간 = 0.070..0.070 행 = 999 루프 = 1) 색인 조건 : (고유 2 9000) 버퍼 : 공유 적중 = 2 읽기 = 3 계획: 버퍼 : 공유 적중 = 3 토토 핫 시간 : 0.162ms 실행 시간 : 0.143 MS
버퍼
쿼리의 어떤 부분이 가장 I/O 집약적인지 식별하는 데 도움이됩니다.
이를 명심하십시오분석 설명
실제로 쿼리를 실행하면 쿼리가 출력 될 수있는 결과가 무엇이든 상관없이 모든 부작용이 평소와 같이 발생합니다.설명
데이터. 테이블을 변경하지 않고 데이터 수정 쿼리를 분석하려면 다음과 같은 나중에 명령을 다시 굴릴 수 있습니다.
시작; Analyze Update Tenk1 세트 백 = 백 + 1 여기서 고유 1 <100; 쿼리 토토 핫 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------. Tenk1에 대한 업데이트 (토토 핫 = 5.06..225.23 행 = 0 너비 = 0) (실제 시간 = 1.634..1.635 행 = 0 루프 = 1) - tenk1의 비트 맵 힙 스캔 (토토 핫 = 5.06..225.23 행 = 100 너비 = 10) (실제 시간 = 0.065..0.141 행 = 100 루프 = 1) COND를 다시 확인하십시오 : (고유 1 <100) 힙 블록 : 정확한 = 90 - tenk1_unique1의 비트 맵 인덱스 스캔 (토토 핫 = 0.00..5.04 행 = 100 너비 = 0) (실제 시간 = 0.031..0.031 행 = 100 루프 = 1) 색인 조건 : (고유 1 <100) 토토 핫 시간 : 0.151 ms 실행 시간 : 1.856ms 롤백;
이 예제에서 볼 수 있듯이 쿼리가 an삽입
, 업데이트
, 삭제
또는병합
명령, 테이블 변경을 적용하는 실제 작업은 최상위 삽입, 업데이트, 삭제 또는 병합 토토 핫 노드로 수행됩니다. 이 노드 아래의 토토 핫 노드는 이전 행을 찾거나 새 데이터를 계산하는 작업을 수행합니다. 따라서 우리는 이미 본 것과 동일한 종류의 비트 맵 테이블 스캔을 볼 수 있으며 출력은 업데이트 된 행을 저장하는 업데이트 노드로 공급됩니다. 데이터 수정 노드에 상당한 양의 실행 시간이 걸릴 수 있지만 (여기서, 시간의 사자 공유를 소비하고 있음) 플래너는 현재 해당 작업을 설명하기 위해 토토 핫 추정치에 아무것도 추가하지는 않습니다. 이 작업은 모든 올바른 쿼리 토토 핫에 대해 동일하므로 계획 결정에 영향을 미치지 않기 때문입니다.
언제업데이트
, 삭제
또는병합
명령은 분할 된 테이블 또는 상속 계층에 영향을 미칩니다. 출력은 다음과 같습니다.
GTEST_PARENT SET 업데이트 설명 f1 = current_date 여기서 f2 = 101; 쿼리 토토 핫 ------------------------------------------------------------------------------------------------ gtest_parent에 대한 업데이트 (토토 핫 = 0.00..3.06 행 = 0 너비 = 0) gtest_child gtest_parent_1에 대한 업데이트 gtest_child2 gtest_parent_2에 대한 업데이트 gtest_child3 gtest_parent_3에 대한 업데이트 - Append (토토 핫 = 0.00..3.06 행 = 3 너비 = 14) - gtest_child gtest_parent_1에서 seq 스캔 (cost = 0.00..1.01 행 = 1 너비 = 14) 필터 : (F2 = 101) - gtest_child2 gtest_parent_2에서 seq 스캔 (cost = 0.00..1.01 행 = 1 너비 = 14) 필터 : (F2 = 101) - gtest_child3 gtest_parent_3에서 seq 스캔 (cost = 0.00..1.01 행 = 1 너비 = 14) 필터 : (F2 = 101)
이 예에서 업데이트 노드는 3 개의 하위 테이블을 고려해야하지만 원래 언급 된 파티션 테이블은 아닙니다 (데이터를 저장하지 않기 때문에). 따라서 테이블 당 하나의 입력 스캐닝 하위 플랜이 있습니다. 명확성을 위해, 업데이트 노드에 주석이 달라서 해당 하위 플랜과 동일한 순서로 업데이트 될 특정 대상 테이블을 표시합니다.
the토토 핫 시간
표시분석 설명
구문 분석 쿼리에서 쿼리 토토 핫을 생성하고 최적화하는 데 걸리는 시간입니다. 구문 분석 또는 재 작성은 포함되지 않습니다.
the실행 시간
표시분석
집행자 스타트 업 및 종료 시간과 해고 된 트리거를 실행할 시간이 포함되어 있지만 구문 분석, 재 작성 또는 토토 핫 시간은 포함되지 않습니다. 실행하는 데 소요되는 시간전
트리거 (있는 경우 트리거) 관련 삽입, 업데이트 또는 삭제 노드의 시간에 포함됩니다. 하지만 실행하는 데 소요되는 시간이후
트리거가 계산되지 않기 때문에이후
트리거는 전체 토토 핫을 완료 한 후 해고됩니다. 각 방아쇠에 소비 된 총 시간 (하나전
또는이후
)도 별도로 표시됩니다. 지연된 제한 조건 트리거는 거래 종료까지 실행되지 않으므로 전혀 고려되지 않습니다.분석 설명
.
최상위 노드에 표시된 시간에는 쿼리의 출력 데이터를 표시 가능한 양식으로 변환하거나 클라이언트로 보내는 데 필요한 시간이 포함되어 있지 않습니다. 하는 동안분석
데이터를 클라이언트로 보내지 않으면 쿼리의 출력 데이터를 표시 가능한 양식으로 변환하고 필요한 시간을 측정하여Serialize
옵션. 그 시간은 별도로 표시되며 총계에도 포함되어 있습니다실행 시간
.
실행 시간에 의해 측정되는 두 가지 중요한 방법이 있습니다분석
동일한 쿼리의 일반 실행에서 벗어날 수 있습니다. 첫째, 출력 행이 클라이언트에게 전달되지 않으므로 네트워크 전송 토토 핫은 포함되지 않습니다. I/O 전환 토토 핫이 포함되어 있지 않으면Serialize
지정되어 있습니다. 둘째,에 의해 추가 된 측정 오버 헤드분석
특히 느린 기계에서 중요 할 수 있습니다gettimeofday ()
운영 시스템 호출. 를 토토 핫할 수 있습니다.토토 베이 PostgreSQL시스템의 타이밍 오버 헤드를 측정하는 도구.
설명
결과를 실제로 테스트하는 것과는 다른 상황에 대한 결과를 추정해서는 안됩니다. 예를 들어 장난감 크기의 테이블의 결과는 큰 테이블에 적용되는 것으로 가정 할 수 없습니다. 플래너의 토토 핫 추정치는 선형이 아니므로 더 크거나 작은 테이블에 대한 다른 계획을 선택할 수 있습니다. 극단적 인 예는 하나의 디스크 페이지만을 차지하는 테이블에서 인덱스 사용 가능 여부에 관계없이 거의 항상 순차적 스캔 계획을 얻을 수 있다는 것입니다. 플래너는 어쨌든 테이블을 처리하기 위해 하나의 디스크 페이지를 읽을 것이라는 것을 알고 있으므로 추가 페이지 읽기를 소비하는 데 인덱스를 보는 데 가치가 없습니다. (우리는 이런 일이 일어나는 것을 보았습니다polygon_tbl
위의 예.)
실제 및 예상 값이 잘 어울리지 않는 경우가 있지만 실제로는 잘못된 것은 없습니다. 그러한 사례 중 하나는 토토 핫 노드 실행이 a에 의해 짧게 중지 될 때 발생합니다.Limit
또는 유사한 효과. 예를 들어,에서Limit
이전에 토토 핫한 쿼리,
설명을 설명하십시오. 쿼리 토토 핫 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------. 한계 (토토 핫 = 0.29..14.33 행 = 2 너비 = 244) (실제 시간 = 0.051..0.071 행 = 2 루프 = 1) - tenk1에서 tenk1_unique2를 사용한 색인 스캔 (토토 핫 = 0.29..70.50 행 = 10 너비 = 244) (실제 시간 = 0.051..0.070 행 = 2 루프 = 1) 색인 조건 : (고유 2 9000) 필터 : (고유 한 <100) 필터로 제거 된 행 : 287 토토 핫 시간 : 0.077ms 실행 시간 : 0.086 ms
인덱스 스캔 노드의 예상 토토 핫 및 행 카운트는 마치 완료로 실행되는 것처럼 표시됩니다. 그러나 실제로 제한 노드는 2 개를 얻은 후 행 요청 중지를 중지 했으므로 실제 행 카운트는 2에 불과하고 런타임은 토토 핫 추정치가 제안하는 것보다 적습니다. 이것은 추정 오류가 아니라 추정치와 실제 값이 표시되는 방식의 불일치 만 있습니다.
합병 결합에는 부적합한 사람들을 혼동 할 수있는 측정 아티팩트도 있습니다. 병합 조인은 다른 입력이 소진되면 하나의 입력 읽기를 중지하고 한 입력의 다음 키 값은 다른 입력의 마지막 키 값보다 큽니다. 이 경우 더 이상 일치 할 수 없으므로 나머지 첫 입력을 스캔 할 필요가 없습니다. 이로 인해 한 아이를 모두 읽지 않고에 언급 된 결과와 같은 결과가 있습니다.Limit
. 또한 외부 (첫 번째) 자식에 중복 키 값이있는 행이 포함되어 있으면 내부 (두 번째) 자식이 백업되고 그 주요 값과 일치하는 행 부분에 대해 철회됩니다..분석
마치 마치 마치 실제 추가 행 인 것처럼 동일한 내부 행의 반복 배출을 계산합니다. 외부 복제물이 많으면 내부 하위 토토 핫 노드에 대한보고 된 실제 행 카운트가 실제로 내부 관계에있는 행의 수보다 훨씬 클 수 있습니다..
비트 맵 및 비트 맵 노드는 구현 제한으로 인해 실제 행 계산이 항상 0으로보고됩니다.
정상적으로,설명
플래너가 만든 모든 토토 핫 노드를 표시합니다. 그러나 실행자가 토토 핫 시간에 사용할 수 없었던 매개 변수 값을 기반으로 행을 생성 할 수 없기 때문에 특정 노드를 실행할 필요가 없다고 판단 할 수있는 경우가 있습니다. (현재 이것은 분할 된 테이블을 스캔하는 Append 또는 Mergeappend 노드의 자식 노드에 대해서만 발생할 수 있습니다.) 이런 일이 발생하면 해당 토토 핫 노드는에서 생략됩니다.설명
출력 및 A하위 토토 핫 제거 :
대신 주석이 나타납니다.n
문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 귀하의 경험 또는 추가 설명이 필요합니다. 사용이 양식문서 문제를보고하려면