IN 조건과 INTERNAL_FUNCTION
·
Oracle/Performance
특정한 경우 DBMS_XPLAN.DISPLAY_CURSOR 결과의 Predicate Information 항목에서 IN 조건이 INTERNAL_FUNCTION으로 표시될 수 있습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다.-- 1DROP TABLE t1 PURGE;CREATE TABLE t1 (c1 NOT NULL, c2 NOT NULL, c3 NOT NULL, c4 NOT NULL, c5 NOT NULL) ASSELECT ROWNUM, ROWNUM, ROWNUM, ROWNUM, ROWNUM FROM XMLTABLE ('1 to 1000000');CREATE INDEX t1_x1 ON t1 (c3, c4, c5); 아래 쿼리는 Predicate Information 항목에서 IN 조건이 OR..
SQL Patch 적용 사례
·
Oracle/Performance
SQL Patch로 CLUSTER_BY_ROWID 힌트를 적용하여 성능을 개선한 사례를 살펴보겠습니다. 글을 작성한 이후 2019년에 이미 유사한 내용의 글을 작성한 것을 알았습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 (c1, c2) AS SELECT NVL (NULLIF (MOD (ROWNUM, 100), 0), 100), LPAD ('X', 100, 'X') FROM XMLTABLE ('1 to 10000'); CREATE INDEX t1_x1 ON t1 (c1); 아래 예제는 나쁜 CF로 인해 1번 오퍼레이션에서 10,000개의 블록 I/O가 발생합니다. -- 2 SELECT /*+ INDEX(A) */ *..
OR Expansion을 사용한 부정형 조건 성능 개선
·
Oracle/Performance
OR Expansion을 사용하면 부정형 조건의 성능을 개선할 수 있습니다. 글을 작성한 후 2018년에 유사한 내용의 글(인덱스와 부정형 조건)을 작성한 사실을 알았습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 (c1, c2, c3) AS SELECT CEIL (ROWNUM / 100000), DECODE (MOD (ROWNUM, 100000), 0, 'N', 'Y'), LPAD ('X', 100, 'X') FROM XMLTABLE ('1 to 1000000'); CREATE INDEX t1_x1 ON t1 (c1, c2); 아래 쿼리는 c2 != 'Y' 조건으로 인해 인덱스 액세스 단계에서 266개의 블록 I/O..
Subquery Pushing과 Execute Call
·
Oracle/Performance
Subquery Pushing으로 동작하는 비상관 단일 행 서브쿼리를 액세스 조건으로 사용하면서브 쿼리가 Execute Call 단계에서 수행됩니다. 이를 통해 쿼리의 성능을 개선한 사례를 살펴보겠습니다. 테스트를 위해 아래와 같이 테이블과 인덱스를 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; DROP TABLE t2 PURGE; CREATE TABLE t1 (c1, c2, c3) AS SELECT CEIL (ROWNUM / 100000), NVL (NULLIF (MOD (ROWNUM, 100000), 0), 100000), LPAD ('X', 100, 'X') FROM XMLTABLE ('1 to 1000000'); CREATE TABLE t2 (c1, c2, c3) AS SELECT..
SCN_ASCENDING 힌트와 Direct Path Read
·
Oracle/Performance
SCN_ASCENDING 힌트는 문서화되지 않은 힌트로 Bug 6688108 - Enhancement: Allow ORA-1555 to be ignored during table scan (Doc ID 6688108.8) 문서에 아래의 설명이 짧게 포함되어 있습니다. 설명에 따르면 이 힌트를 기술한 쿼리는 Undo 재사용으로 인해 Consistent Read가 불가능한 경우 ORA-1555 에러를 발생시키지 않고 새로운 쿼리(snapshot) SCN으로 블록을 액세스하며, 이로 인해 읽기 일관성을 보장하지 않습니다. ORA-1555 can occur during long running queries involving a ROWID Range or full table scan if the undo has ..
UNUSABLE 인덱스 파티션에 의한 Join Factorization 쿼리 변환
·
Oracle/Performance
UNUSABLE 인덱스 파티션에 의한 Join Factorization 쿼리 변환으로 인해 쿼리의 성능이 저하된 사례를 살펴보겠습니다. 참고로 이 글은 PPWJ 성능 저하 사례와 관련이 있습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다. t1은 비파티션 테이블, t2는 파티션 테이블입니다. t1 테이블에는 t2 테이블의 p1, p2 파티션에 해당하는 데이터가 저장되어 있습니다. -- 1 DROP TABLE t1 PURGE; DROP TABLE t2 PURGE; CREATE TABLE t1 (c1, c2) AS SELECT CEIL ((ROWNUM + 600000) / 100000), ROWNUM + 600000 FROM XMLTABLE ('1 to 200000'); CREATE TABLE t2..
PPWJ(Partial-Partition Wise Join) 성능 저하 개선
·
Oracle/Performance
기준 데이터를 저장한 비파티션 임시 테이블과 실제 데이터를 저장한 파티션 테이블을 병렬 조인하는 경우 임시 테이블의 기준 데이터에 따라 PPWJ(Partial-Partition Wise Join)의 성능이 저하될 수 있습니다. 이 글에서 분배 방식을 변경하여 PPWJ 성능 저하를 개선한 사례를 살펴보겠습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다. t1 테이블은 기준 데이터를 저장하는 비파티션 임시 테이블, t2 테이블은 실제 데이터를 저장하는 파티션 테이블입니다.-- 1DROP TABLE t1 PURGE;DROP TABLE t2 PURGE;CREATE GLOBAL TEMPORARY TABLE t1 (c1 NUMBER);CREATE TABLE t2 (c1)PARTITION BY RANGE (..
Block Range Granules
·
Oracle/Performance
블록 그래뉼(Block Range Granules)의 개수와 크기는 동적으로 결정되지만 아래 파라미터로 그래뉼의 생성 방식을 조정할 수 있습니다. 파라미터에 따르면 블록 그래뉼의 기본 크기는 1GB이며, PX 서버 별로 최소 13개, 최대 100개의 그래뉼이 생성될 수 있습니다. NAME DISPLAY_VALUE DEFAULT_VALUE DESCRIPTION --------------------------- ------------- ------------- ------------------------------------------------------------ _px_granule_size 1000000 1000000 default size of a rowid range granule (in KB) ..
TBL$OR$IDX$PART$NUM 함수
·
Oracle/Performance
TBL$OR$IDX$PART$NUM 함수는 파티션과 관련된 문서화되지 않은 함수로 파티션과 서브파티션의 포지션 또는 오브젝트 ID를 반환하며, 내부적으로 파티션 Pruning을 위해 사용됩니다. TBL$OR$IDX$PART$NUM 함수의 구문은 아래와 같습니다. 첫 번째 파라미터는 파티션 테이블을 입력합니다. 두 번째 파라미터는 기본적으로 0을 입력하며, 글로벌 파티션 인덱스의 오브젝트 ID를 입력하면 인덱스에 대한 파티션 정보가 반환됩니다. 세 번째 파라미터는 반환 값을 결정합니다. 1은 파티션의 포지션, 0은 서브파티션의 포지션, 4는 파티션의 오브젝트 ID, 3은 서브파티션의 오브젝트 ID를 반환하며, 8을 Deffered Global 인덱스에 대한 파티션 Pruning에 사용하는 것으로 보입니다...
에러 메시지 생성 부하
·
Oracle/Performance
2018년 1월 29일 네이버 카페에 작성한 "_suppress_identifiers_on_dupkey 파라미터" 글을 보완한 글입니다. 에러가 대량으로 발생하면 에러 메시지를 생성하기 위한 부가적인 부하로 인해 성능 저하가 발생할 수 있습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 (c1 NUMBER, c2 NUMBER); CREATE UNIQUE INDEX t1_u1 ON t1 (c1); 아래 예제는 INSERT 문을 수행하고 DUP_VAL_ON_INDEX 예외가 발생하면 UPDATE 문을 수행하는 방식을 보여줍니다. 이런 방식을 INSERT & UPDATE 방식이라고 합니다. -- 2 SET SERVEROUT ..
Unpivoted V$SQL_SHARED_CURSOR 뷰
·
Oracle/Performance
V$SQL_SHARED_CURSOR 뷰는 특정 자식 커서가 기존 자식 커서와 공유되지 않는 이유를 보여줍니다. 하지만 64개의 여부 속성을 통해 커서를 공유할 수 없는 이유를 파악해야 하므로 편이성이 떨어집니다. 편이성을 높이기 위해 아래와 같이 64개의 여부 속성이 unpivot된 뷰를 생성하겠습니다. SYS.X$KKSCS 테이블은 V$SQL_SHARED_CURSOR 뷰의 베이스 테이블로 bitvector 칼럼에 커서를 공유할 수 없는 이유를 저장합니다. -- 1-1 CREATE OR REPLACE VIEW sys.gu_$sql_shared_cursor AS SELECT inst_id , sql_id , address , child_address , child_number , reason , reaso..
Parallel Conventional Load
·
Oracle/Performance
병렬 INSERT 문에 NOAPPEND 힌트를 사용하면 데이터를 Conventional Path로 적재할 수 있습니다. 테스트를 위해 아래와 같이 테이블을 생성하고, _optimizer_gather_stats_on_load 파라미터를 FALSE로 설정하겠습니다. -- 1-1 DROP TABLE t1 PURGE; DROP TABLE t2 PURGE; CREATE TABLE t1 (c1 NUMBER); CREATE TABLE t2 (c1) AS SELECT ROWNUM FROM XMLTABLE ('1 to 1000000'); -- 1-2 ALTER SESSION SET "_optimizer_gather_stats_on_load" = FALSE; 아래는 병렬 DML이 활성화되지 않은 병렬 INSERT 문의 실..