다중 키 해시 파티션
·
Oracle/Performance
다중 키로 생성한 해시 파티션의 조회 방식을 테스트하기 위해 아래와 같이 테이블을 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 (c1 NUMBER, c2 NUMBER, c3 NUMBER) PARTITION BY HASH (c1, c2, c3) PARTITIONS 256; 전체 파티션 키를 등호(=)로 입력하면 단일 파티션이 조회됩니다. -- 2 SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1 AND c3 = 1; ------------------------------------------------------ | Id | Operation | Name | Pstart| Pstop | ----------------------------..
병렬 MERGE 문의 데이터 분배
·
Oracle/Performance
병렬 MERGE 문은 아래의 두 가지 데이터 분배 방식을 사용합니다. 12.0.1.2 이상 버전은 타깃 테이블이 비파티션 테이블인 경우 PX SEND (ROWID RANDOM) 분배 방식을 사용하고, 타깃 테이블이 파티션 테이블인 경우 PX SEND HYBRID (ROWID PKEY) 분배 방식을 사용합니다. 타깃 테이블이 파티션 테이블인 경우 삽입되는 데이터에 따라 데이터 분배가 불균형할 수 있습니다. PX SEND (ROWID RANDOM) 분배 방식: UPDATE는 ROWID 범위, INSERT는 RANDOM 방식으로 분배 PX SEND HYBRID (ROWID PKEY) 분배 방식: UPDATE는 ROWID 범위, INSERT는 PK 범위로 분배 테스트를 위해 아래와 같이 t1, t2, t3 테이..
자동 통계 수집과 STALE_PERCENT
·
Oracle/Performance
자동 통계 수집은 STALE_PERCENT 설정과 관련이 있습니다. 테스트를 위해 아래와 같이 100개의 로우를 가진 t1 테이블을 생성하고, DBMS_STATS.GATHER_TABLE_STATS 프로시저로 t1 테이블의 통계를 수집하겠습니다. -- 1-1 DROP TABLE t1 PURGE; CREATE TABLE t1 AS SELECT ROWNUM AS c1 FROM XMLTABLE ('1 to 100'); -- 1-2 EXEC DBMS_STATS.GATHER_TABLE_STATS ('TUNA', 'T1') PL/SQL 처리가 정상적으로 완료되었습니다. DBMS_STATS.GET_PREFS 함수로 통계의 기본 설정(preferences)을 조회할 수 있습니다. 아래 쿼리는 t1 테이블의 STALE_P..
NL 조인의 결과 순서
·
Oracle/Performance
NL 조인은 기본적으로 아우터의 순서로 결과를 반환하지만, NLJ_BATCHING 방식으로 동작하는 NL 조인은 물리 I/O가 발생할 경우 아우터의 순서로 결과를 반환하지 않을 수 있습니다. 아울러 NL 조인의 이너에서 테이블을 액세스하지 않아도 아우터의 순서로 결과를 반환하지 않을 수 있습니다. 테스트를 위해 아래와 같이 테이블과 인덱스를 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; DROP TABLE t2 PURGE; CREATE TABLE t1 (c1, c2) AS SELECT ROWNUM, ROWNUM FROM XMLTABLE ('1 to 10000'); CREATE TABLE t2 (c1, c2) AS SELECT ROWNUM, ROWNUM FROM XMLTABLE ('1 to..
조인 칼럼의 low_value와 high_value에 의한 조인 카디널리티
·
Oracle/Performance
조인 칼럼의 low_value와 high_value는 조인 카디널리티 계산에 영향을 줍니다. 조인 칼럼의 high_value가 다른 조인 칼럼의 low_value와 값이 겹치지 않으면 조인 카디널리티가 1로 계산되어 비효율적인 실행 계획이 생성될 수 있습니다. 테스트를 위해 아래와 같이 t1, t2 테이블을 생성하겠습니다. 두 테이블 모두 2021-01-01부터 2022-12-31까지 데이터가 존재하고 2021-12-31 이후 통계를 수집하지 않았다고 가정합니다. -- 1-1 DROP TABLE t1 PURGE; DROP TABLE t2 PURGE; CREATE TABLE t1 AS SELECT ROWNUM AS c1 , DATE '2020-12-31' + CEIL (ROWNUM / 100) AS c2 ..
low_value와 high_value를 벗어난 값에 대한 예상 카디널리티
·
Oracle/Performance
통계 수집을 중단한 후 특정 기간이 경과하면 low_value와 high_value를 벗어난 값의 예상 카디널리티가 선형적으로 감소하기 때문에 비효율적인 실행계획이 수립될 수 있습니다. 테스트를 위해 아래와 같이 t1 테이블을 생성하겠습니다. 통계 수집시 히스토그램을 생성하지 않았습니다. -- 1-1 DROP TABLE t1 PURGE; CREATE TABLE t1 AS SELECT ROWNUM AS c1 , DATE '2020-12-31' + CEIL (ROWNUM / 100) AS c2 FROM XMLTABLE ('1 to 36500'); -- 1-2 EXEC DBMS_STATS.GATHER_TABLE_STATS (ownname => 'TUNA', tabname => 'T1', method_opt =..
OR 조인 조건을 사용한 아우터 조인의 성능 저하 #1
·
Oracle/Performance
19c에서 INSERT 문이나 CTAS 문에 OR 조인 조건이 있는 아우터 조인을 사용하면 비효율적인 실행 계획으로 인해 성능이 저하될 수 있습니다. 테스트를 위해 아래의 테이블을 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; DROP TABLE t2 PURGE; DROP TABLE t3 PURGE; CREATE TABLE t1 (c1 NUMBER, c2 NUMBER, c3 NUMBER); CREATE TABLE t2 (c1 NUMBER, c2 NUMBER, c3 NUMBER); CREATE TABLE t3 (c1 NUMBER, c2 NUMBER); 아래 쿼리는 OR 조인 조건을 사용했지만 b.c1 = a.c1 조건으로 해시 조인으로 아우터 조인을 수행합니다. OR 조인 조건인 a.c2 ..
Historical SQL Monitor Report
·
Oracle/Performance
12.1 버전부터 SQL Monitor Report 데이터가 AWR에 저장됩니다. 아래와 같이 DBMS_AUTO_REPORT.REPORT_REPOSITORY_DETAIL 함수로 Historical SQL Monitor Report를 생성할 수 있습니다. rid에 리포트 ID, type에 TEXT 또는 ACTIVE를 입력합니다. -- 1 SELECT DBMS_AUTO_REPORT.REPORT_REPOSITORY_DETAIL (rid => :v_rid, type => 'TEXT') AS report FROM DUAL; 아래 쿼리로 Historical SQL Monitor Report의 리포트 ID를 조회할 수 있습니다. DBA_HIST_REPORTS는 AWR로 캡처된 XML 보고서에 대한 정보를 표시합니다...
로우 랜덤 조회
·
Oracle/Performance
개요 랜덤 Ton-N 쿼리를 사용하지 않아도 로우를 랜덤하게 조회할 수 있습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다. t1 테이블에는 10,000,000개의 행이 저장되어 있습니다. -- 1 DROP TABLE t1 PURGE; DROP TABLE t2 PURGE; DROP TABLE t3 PURGE; DROP TABLE t4 PURGE; CREATE TABLE t1 (c1, c2) AS SELECT ROWNUM, LPAD ('X', 100, 'X') FROM XMLTABLE ('1 to 10000000'); CREATE TABLE t2 (c1 NUMBER, c2 VARCHAR2(100)); CREATE TABLE t3 (c1 NUMBER, c2 VARCHAR2(100)); CREATE ..
병렬 쿼리에서 사용자 정의 함수의 동작 #2
·
Oracle/Performance
병렬 쿼리에서 패키지 변수를 사용한 사용자 정의 함수는 PARALLEL_ENABLE 키워드의 기술 여부에 따라 동작이 달라질 수 있습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 AS SELECT ROWNUM AS c1, LPAD ('X', 4000, 'X') AS c2 FROM XMLTABLE ('1 to 8'); 아래 f1, f2 함수는 세션 ID와 pkg1.gv1 패키지 변수에 1을 더한 값을 반환합니다. 아울러 f2 함수에만 PARALLEL_ENABLE 키워드를 사용합니다. -- 2-1 DROP PACKAGE pkg1; CREATE OR REPLACE PACKAGE pkg1 IS gv1 NUMBER := 0; ..
병렬 쿼리에서 사용자 정의 함수의 동작 #1
·
Oracle/Performance
병렬 쿼리에서 사용자 정의 함수는 사용 방법과 실행 위치에 따라 동작이 달라질 수 있습니다. 테스트를 위해 아래와 같이 테이블을 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 AS SELECT ROWNUM AS c1, LPAD ('X', 4000, 'X') AS c2 FROM XMLTABLE ('1 to 8'); 아래 f1 함수는 세션 ID를 반환합니다. -- 2 CREATE OR REPLACE FUNCTION f1 (i_v1 IN NUMBER) RETURN NUMBER IS BEGIN RETURN SYS_CONTEXT ('USERENV', 'SID'); END; / 아래 쿼리는 f1 함수를 사용합니다. PX 서버가 f1 함수를 수행하여 4개의 세션 ID가 반..
중복 제거에 대한 DISTINCT 키워드와 GROUP BY 절
·
Oracle/Performance
중복 제거에 DISTINCT 키워드와 GROUP BY 절을 사용할 수 있습니다. 성능 측면에서 동일하지만 의미 측면에서 DISTINCT 키워드를 사용하는 편이 바람직합니다. 테스트를 위해 아래의 테이블을 생성하겠습니다. -- 1 DROP TABLE t1 PURGE; CREATE TABLE t1 AS SELECT LPAD (MOD (ROWNUM, 100), 100, '0') AS c1 FROM XMLTABLE ('1 to 100000'); 아래와 같이 중복 제거에 DISTINCT 키워드와 GROUP BY 절을 사용한 쿼리를 수행하고 SQL ID를 조회하겠습니다. -- 2-1 SELECT DISTINCT c1 FROM t1; ... 100 행이 선택되었습니다. --------------------------..