구분 | 설명 |
---|---|
Distinct Count | Number of Distinct Values |
Density | 컬럼값의 밀도(1 / NDV) |
Skewness | Data가 특정 값에 몰려있을 경우 Dkewness가 높다고 함 Historgram이 존재하는 경우 Skewness를 반영하기 위해 별도의 Density를 계산 |
Selectivity | 특정 조건의 선택도를 의미 Density는 특정 컬럼(하나)의 고정된 값인 반면 Selectivity는 동적 컬럼의 값 |
-- create objects
DROP TABLE T1 PURGE;
CREATE TABLE T1(C1 INT, C2 INT, C3 DATE, C4 VARCHAR2(14));
-- GENERATE DATA AND GATHER STATISTICS
INSERT INTO T1
SELECT LEVEL, -- HIGHLY SELECTIVE
MOD(ABS(DBMS_RANDOM.RANDOM), 10), -- HIGHLY UNSELECTIVE
TO_DATE('20080301', 'YYYYMMDD') - MOD(LEVEL, 100),
TO_CHAR(TO_DATE('20080301', 'YYYYMMDD') - MOD(LEVEL, 100), 'YYYYMMDD')
FROM DUAL
CONNECT BY LEVEL <= 10000
;
-- gather stats "without" histogram
EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T1', METHOD_OPT=>'FOR ALL COLUMNS SIZE 1');
-- function
CREATE OR REPLACE FUNCTION F1(p_num IN NUMBER) RETURN NUMBER IS
v_num NUMBER;
BEGIN
SELECT p_num + 1
INTO v_num
FROM DUAL;
RETURN v_num;
END;
-- Table
SELECT TABLE_NAME,
NUM_ROWS,
BLOCKS,
SAMPLE_SIZE,
TO_CHAR(LAST_ANALYZED, 'YYYY/MM/DD HH24:MI:SS') AS LAST_ANAL
FROM USER_TAB_STATISTICS
WHERE TABLE_NAME = UPPER('T1')
;
TABLE_NAME | NUM_ROWS | BLOCKS | SAMPLE_SIZE | LAST_ANAL |
---|---|---|---|---|
T1 | 10000 | 43 | 10000 | 2009-02-23 7:28:37 PM |
-- Column
SELECT S.TABLE_NAME,
S.COLUMN_NAME,
S.NUM_DISTINCT,
S.NUM_NULLS,
S.DENSITY,
S.LOW_VALUE,
S.HIGH_VALUE,
S.HISTOGRAM
FROM USER_TAB_COLS S
WHERE S.TABLE_NAME = UPPER('T1')
;
TABLE_NAME | COLUMN_NAME | NUM_DISTINCT | NUM_NULLS | DENSITY | LOW_VALUE | HIGH_VALUE | HISTOGRAM |
---|---|---|---|---|---|---|---|
T1 | C4 | 100 | 0 | 0.01 | 3230303731313230 | 3230303830333030 | NONE |
T1 | C3 | 100 | 0 | 0.01 | 786B0B17010101 | 786C0301010101 | NONE |
T1 | C2 | 10 | 0 | 0.1 | 80 | C10A | NONE |
T1 | C1 | 10000 | 0 | 0.0001 | C102 | C302 | NONE |
-- Histogram
SELECT TABLE_NAME,
COLUMN_NAME,
ENDPOINT_NUMBER,
ENDPOINT_VALUE || '(' || ENDPOINT_ACTUAL_VALUE || ')' AS ENDPOINT_VALUE
FROM USER_TAB_HISTOGRAMS
WHERE TABLE_NAME = UPPER('T1')
ORDER BY COLUMN_NAME,
ENDPOINT_NUMBER
;
TABLE_NAME | COLUMN_NAME | ENDPOINT_NUMBER | ENDPOINT_VALUE |
---|---|---|---|
T1 | C1 | 0 | 1() |
T1 | C1 | 1 | 10000() |
T1 | C2 | 0 | 1() |
T1 | C2 | 1 | 9() |
T1 | C3 | 0 | 2454428() |
T1 | C3 | 1 | 2454527() |
T1 | C4 | 0 | 260592218620663000000000000000000000() |
T1 | C4 | 1 | 260592218928948000000000000000000000() |
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C1 = 1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 23 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 1 | 23 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C2 = 1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000 | 23000 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 1000 | 23000 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C1 = :B1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 23 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 1 | 23 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * (Selectivity(C1 BETWEEN X AND Y))
= Base Cardinality * (Selectivity(C1 = X) + Selectivity(C1 = Y) + Selectivity(X < C1 < Y))
= Base Cardinality * (Selectivity(C1 = X) + Selectivity(C1 = Y) + (Y - X)/(MAX - MIN))
= Base Cardinality * (Selectivity(C1 = 1) + Selectivity(C1 = 100) + (100 - 1)/(10000 - 1))
= 10000 * (0.0001 + 0.0001 + (99)/(9999))
= 10000 * (0.0001 + 0.0001 + 0.00990099)
= 10000 * 0.01000099
= 100
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C1 BETWEEN 1
AND 100
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 2300 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 100 | 2300 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * (Selectivity(C1 BETWEEN X AND Y)) * (SELECTIVITY(C2 = 1))
= 10000 * 0.01 * 0.1
= 0.001
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C1 BETWEEN 1
AND 100
AND C2 = 1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 230 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 10 | 230 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * (Selectivity(P1 OR P2))
= Base Cardinality * (Selectivity(P1) + Selectivity(P2) - Selectivity(P1 AND P2))
= Base Cardinality * (Selectivity(P1) + Selectivity(P2) - (Selectivity(P1) * Selectivity(P2)))
= 10000 * (0.01 + 0.1 - (0.01 * 0.1))
= 10000 * (0.109) = 1090
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C1 BETWEEN 1
AND 100
OR C2 = 1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1090 | 25070 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 1090 | 25070 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * Selectivity
= 10000 * 0.01
= 100
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C3 = TO_DATE('20080201', 'YYYYMMDD')
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 2300 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 100 | 2300 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * Selectivity
= 10000 * 0.01
= 100
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C3 = '20080201'
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 2300 | 14 (8)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 100 | 2300 | 14 (8)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * (Selectivity(C3 BETWEEN P1 AND P2))
= Base Cardinality * (Selectivity(P1) + Selectivity(P2) + Selectivity(P1 < C1 < P2))
= Base Cardinality * (Selectivity(P1) + Selectivity(P2) + (P2 - P1)/(MAX - MIN))
= 10000 * (0.01 + 0.01 + (2008/01/10 - 2007/12/31) / (2008/03/01 - 2007/11/23))
= 10000 * (0.01 + 0.01 + (10)/(99))
= 10000 * 0.121010101
= 1210
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C3 BETWEEN TO_DATE('20071231', 'YYYYMMDD')
AND TO_DATE('20080110', 'YYYYMMDD')
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1210 | 27830 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 1210 | 27830 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * (Selectivity(C4 BETWEEN P1 AND P2))
= Base Cardinality * (Selectivity(P1) + Selectivity(P2) + Selectivity(P1 < C4 < P2))
= Base Cardinality * (Selectivity(P1) + Selectivity(P2) + (P2 - P1)/(MAX - MIN))
= 10000 * (0.01 + 0.01 + (20080110 - 20071231) / (20080301 - 20071123))
= 10000 * (0.01 + 0.01 + (8879) / (9178))
= 10000 * 0.987422096
= 9874
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C4 BETWEEN '20071231'
AND '20080110'
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9874 | 221K| 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 9874 | 221K| 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
구분 | 공식 |
---|---|
Equals | = Base Cardinality * Selectivity |
Between | = Base Cardinality * (Selectivity(C1 BETWEEN P1 AND P2)) = Base Cardinality * (Selectivity(P1) + Selectivity(P2) + Selectivity(P1 < C1 < P2)) = Base Cardinality * (Selectivity(P1) + Selectivity(P2) + (P2 - P1)/(MAX - MIN)) |
2개 이상 AND | = Base Cardinality * Selectivity(P1) * Selectivity(P2) |
2개 이상 OR | = Base Cardinality * (Selectivity(P1 OR P2)) = Base Cardinality * (Selectivity(P1) + Selectivity(P2) - Selectivity(P1 AND P2)) = Base Cardinality * (Selectivity(P1) + Selectivity(P2) - (Selectivity(P1) * Selectivity(P2))) |
'Magic Number'란 {*}{+}오라클이 조건값을 측정할 수 없을 경우 임의의 값을 사용하는것을 의미{+}{*}
= Base Cardinality * 0.05
= 10000 * 0.05
= 500
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C1 > :B1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 500 | 11500 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 500 | 11500 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * (C1 >= :B1) * (C1 <= B2)
= 10000 * 0.05 * 0.05
= 25
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C1 BETWEEN :B1
AND :B2
;
select * from table(dbms_xplan.display);
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 575 | 13 (0)| 00:00:01 |
|* 1 | FILTER | | | | | |
|* 2 | TABLE ACCESS FULL| T1 | 25 | 575 | 13 (0)| 00:00:01 |
---------------------------------------------------------------------------
= Base Cardinality * 0.01
= 10000 * 0.01
= 100
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE F1(C1) = 1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 2300 | 16 (19)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 100 | 2300 | 16 (19)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * 0.05
= 10000 * 0.05
= 500
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE F1(C1) > 1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 500 | 11500 | 16 (19)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 500 | 11500 | 16 (19)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * (C1 >= :B1) * (C1 <= B2)
= 10000 * 0.05 * 0.05
= 25
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE F1(C1) BETWEEN 1
AND 100
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 575 | 16 (19)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 25 | 575 | 16 (19)| 00:00:01 |
--------------------------------------------------------------------------
= Dencity 적용
= Base Cardinality * Selectivity
= 10000 * 0.0001
= 1
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C1 = F1(C1)
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 23 | 16 (19)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 1 | 23 | 16 (19)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * Selectivity
= 10000 * 0.01
= 100
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C4 LIKE '20080101'
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 2300 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 100 | 2300 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * 0.05
= 10000 * 0.05
= 500
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C4 LIKE :B1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 500 | 11500 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 500 | 11500 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * Selectivity
= 10000 * 0.01
= 100
EXPLAIN PLAN FOR
SELECT /*+ OPT_PARAM('_LIKE_WITH_BIND_AS_EQUALITY', 'TRUE') */
*
FROM T1
WHERE C4 LIKE :B1
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 101 | 2323 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 101 | 2323 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
= Base Cardinality * 0.05
= 10000 * 0.05
= 500
EXPLAIN PLAN FOR
SELECT *
FROM T1
WHERE C4 LIKE '%2008'
;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 500 | 11500 | 13 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T1 | 500 | 11500 | 13 (0)| 00:00:01 |
--------------------------------------------------------------------------
- 강좌 URL : http://www.gurubee.net/lecture/3884
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.