DBMS_SESSION.SLEEP 프로시저 정밀도
·
Oracle/PLSQL
DBMS_SESSION.SLEEP 프로시저의 정밀도는 1/100 초입니다. 정밀도가 1/1000 초(ms)인 Thread.Sleep 메서드 (Java.Lang)의 1/10 수준으로 낮은 정밀도로 인해 정확한 스케쥴링을 구현하기 어렵습니다.Amount of time, in seconds, to suspend the session. The smallest increment can be entered in hundredths of a second; for example, 1.95 is a legal time value. 특히 주의할 점은 DBMS_SESSION.SEELP 프로시저의 입력 값을 반올림됨으로써 대기 시간이 증가할 수 있다는 것입니다. 아래는 DBMS_SESSION.SEELP 프로시저를 테스트한 결..
파티셔닝을 통한 GC 경합 해소
·
Oracle/Performance
예전에 작성한 Right Growing Index 경합 해소 글에서 인스턴스 ID의 가상 칼럼을 서브 파티션 키로 사용해 GC 경합을 해소하는 방법을 소개했습니다. 이 방법은 아래와 같이 이미 서브 파티션을 생성한 경우에는 사용할 수 없습니다. 이번 글에서 다중 칼럼 리스트 파티션을 사용해 GC 경합을 해소하는 방법을 살펴보겠습니다.-- 1CREATE TABLE t1 ( dt DATE , id NUMBER , vl NUMBER)PARTITION BY RANGE (dt)SUBPARTITION BY HASH (id) SUBPARTITION TEMPLATE ( SUBPARTITION sp_1 , SUBPARTITION sp_2) ( PARTITION p_20240101 VALUES LES..
SQL 파싱 순서
·
Oracle/Performance
SQL Tuning Guide는 SQL 파싱이 Syntax Check -> Semantic Check -> Shared Pool Check 순서로 수행된다고 설명하고 있지만 실제로는 Shared Pool Check가 가장 먼저 수행되는 것으로 보입니다. 테스트를 위해 아래와 같이 Shared Pool을 Flush하겠습니다. -- 1-1 ALTER SYSTEM FLUSH SHARED_POOL; -- 1-2: SYS SELECT kglnaobj, kglhdnsd, kglobt03, kglobhd6 FROM x$kglcursor WHERE kglhdadr != kglhdpar AND kglnaobj IN ('SELECT * FORM T1', 'SELECT * FROM T1'); no rows selected ..
INDEX_STATS 힌트
·
Oracle/Performance
지난 COLUMN_STATS 힌트 글에 이어 INDEX_STATS 힌트의 동작을 살펴보겠습니다. INDEX_STATS 힌트의 구문은 아래와 같습니다. /*+ INDEX_STATS(tablespec indexspec method adjustment) */ method에 아래의 항목을 사용할 수 있습니다. { SET | SCALE | SAMPLE | DEFAULT } adjustment는 아래의 형식으로 사용하며 다수의 항목을 함께 사용할 수 있습니다. { BLOCKS | KEYS | CLUSTERING_FACTOR | INDEX_ROWS } = value 테스트를 위해 아래과 같이 테이블과 인덱스를 생성하고 통계정보를 수집하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t..
COLUMN_STATS 힌트
·
Oracle/Performance
지난 TABLE_STATS 힌트 글에 이어 COLUMN_STATS 힌트의 동작을 살펴보겠습니다. COLUMN_STATS 힌트의 구문은 아래와 같습니다. /*+ COLUMN_STATS(tablespec columnspec method adjustment) */ method에 아래의 항목을 사용할 수 있습니다. { SET | SCALE | SAMPLE | DEFAULT } adjustment는 아래의 형식으로 사용하며 다수의 항목을 함께 사용할 수 있습니다. { DISTINCT | NULLS | LENGTH | MIN | MAX } = value 테스트를 위해 아래과 같이 테이블을 생성하고 통계정보를 수집하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 (c1 NUMBE..
TABLE_STATS 힌트
·
Oracle/Performance
OPT_ESTIMATE 힌트처럼 아래의 세 가지 힌트도 SQL Tuning Advisor(STA)가 내부적으로 사용하는 문서화되지 않은 힌트입니다. 이번 글에서 TABLE_STATS 힌트의 동작을 살펴보고, 다음 글에서 COLUMN_STATS, INDEX_STATS 힌트를 살펴보겠습니다. SELECT name , RTRIM (CASE WHEN BITAND (target_level, 1) != 0 THEN 'STATEMENT + ' END || CASE WHEN BITAND (target_level, 2) != 0 THEN 'QUERY BLOCK + ' END || CASE WHEN BITAND (target_level, 4) != 0 THEN 'OBJECT + ' END || CASE WHEN BITAN..
Unpivot Pipelined Function
·
Oracle/PLSQL
APEX 개발에 사용하기 위해 Ref 커서를 입력받아 Unpivot한 결과를 반환하는 Pipelined Function을 작성했습니다. 아래와 같이 패키지를 생성하겠습니다. DBMS_SQL.TO_CURSOR_NUMBER 프로시저로 Ref 커서를 DBMS_SQL 커서로 변경하는 부분을 제외하면 Tom Kyte가 개발한 print_table 프로시저와 동작 방식이 동일합니다. -- 1-1 CREATE OR REPLACE PACKAGE pkg_unpivot IS TYPE trd IS RECORD ( name VARCHAR2(4000) , value VARCHAR2(4000) ); TYPE tnt IS TABLE OF trd; FUNCTION fnc_get_value ( i_cursor IN SYS_REFCUR..
OPT_ESTIMATE 힌트
·
Oracle/Performance
OPT_ESTIMATE 힌트는 SQL Tuning Advisor(STA)가 내부적으로 사용하는 문서화되지 않은 힌트입니다. SELECT name , RTRIM (CASE WHEN BITAND (target_level, 1) != 0 THEN 'STATEMENT + ' END || CASE WHEN BITAND (target_level, 2) != 0 THEN 'QUERY BLOCK + ' END || CASE WHEN BITAND (target_level, 4) != 0 THEN 'OBJECT + ' END || CASE WHEN BITAND (target_level, 8) != 0 THEN 'JOIN + ' END, '+ ') AS target_level , version FROM v$sql_hint ..
IN 조건에 대한 INTERNAL_FUNCTION과 오프로딩
·
Exadata
문자 값이 암시적 데이터 변환에 의해 날짜 값으로 변환되면 INTERNAL_FUNCTION로 표시되고 스토리지 인덱스를 사용할 수 없게 됩니다. 이와 관련하여 예전에 암시적 데이터 변환과 오프로딩 글을 작성했습니다. 앞서 작성한 IN 조건과 INTERNAL_FUNCTION 글도 INTERNAL_FUNCTION으로 표시된 IN 조건의 스토리지 인덱스 사용 여부에 대한 검증을 위해 작성했습니다. 테스트를 위해 아래와 같이 테이블을 생성하고, _serial_direct_read 파라미터를 ALWAYS로 설정하겠습니다. -- 1-1 DROP TABLE t1 PURGE; CREATE TABLE t1 (c1, c2, c3) NOLOGGING AS SELECT 1, CEIL (ROWNUM / 1000000), LPA..
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..
HCC 압축 후 블록 I/O 증가 현상
·
Exadata
테이블을 HCC 압축하면 인덱스를 통해 테이블을 액세스하는 쿼리의 블록 I/O가 증가하고 이로 인해 쿼리의 성능이 저하될 수 있습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 ( c01, c02, c03, c04, c05, c06, c07, c08, c09, c10 , c11, c12, c13, c14, c15, c16, c17, c18, c19, c20 , c21, c22, c23, c24, c25, c26, c27, c28, c29, c30 ) NOLOGGING PARALLEL 10 PARTITION BY RANGE (c01) ( PARTITION p01 VALUES LESS THAN ( 2) , PARTITION..
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) */ *..