๐กSQL TUNING
DB time์ด๋ผ๊ณ ๋ ๋ถ๋ฆฌ๋ ์ฒ๋ฆฌ ์๊ฐ์ SQL ์คํ ์๋ + ๋๊ธฐ ์๊ฐ์ผ๋ก ๊ตฌ์ฑ๋๋ค. ์ด๋, SQL ์คํ ์๋๋ฅผ ์ค์ฌ ์ ์ฒด์ ์ธ ์ฒ๋ฆฌ ์๊ฐ์ ์ค์ด๋ ๊ณผ์ ์ SQL TUNING์ด๋ผ๊ณ ํ๋ค.

์ค๋ผํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ๋ ์ธ์คํด์ค์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ๊ตฌ์ฑ๋์ด ์๋ค.
์ค๋ผํด์ด ์ฌ์ฉํ๋ 3๊ฐ์ง ํ์ ์ ๋ฌผ๋ฆฌ์ ์ ์ฅ ํ์ผ์ด ์๋ค.
์ค๋ผํด ์ธ์คํด์ค๋ System Global Aread๋ผ๋ ๋ฉ๋ชจ๋ฆฌ ๊ตฌ์กฐ์ ์ธ์คํด์ค ์คํ๊ณผ ๊ด๋ จ๋ ๋ใ ๋ถ๋ถ์ ์์ ์ ์ฒ๋ฆฌํ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค๋ก ๊ตฌ์ฑ๋๋ค. ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค์ ์์๋ก๋ Shared Pool, Streams Pool, Large Pool, Java Pool, Database Buffer Cache, Redo Log Buffer ๋ฑ์ด ์๋ค.
์ค๋ผํด์ด ๋ฐ ๋ OS์๊ฒ ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ์๊ตฌํด SGA์ ํด๋นํ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ๋ณดํ๊ฒ ๋๋ค. ์ดํ ๋์์ผ ํ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค๊น์ง ๋์ฐ๋ ๊ฒ์ด STARTUP ๋ช ๋ น์ด์ ์ญํ ์ด๋ค.
์ดํ์ SELECT, UPDATE ๋ฑ์ด ๊ฐ๋ฅํ๋ฐ, ๊ทธ ๋ง์ ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค๊ฐ ๋ช ๋ น์ด ์ฒ๋ฆฌ๋ฅผ ์ํด ๋ฐ๋์ ํ์ํ๋ค๋ ๋ป์ด๋ค.
์ฌ๋ฌ ๋ฐฑ๊ทธ๋ผ์ด๋ ํ๋ก์ธ์ค ์ค์์ Shared Pool, Database Buffer Cache, Redo Log Buffer๋ ํ์์ ์ผ๋ก ์คํ๋๋ค. ์ฆ, ์ด ์ธ ๊ฐ์ ํ๋ก์ธ์ค๋ ๋ฌด์กฐ๊ฑด ์์ด์ผ ๋ช ๋ น์ด ์คํํ ์ค๋น๊ฐ ๊ฐ๋ฅํด์ง๋ค๋ ๊ฒ์ด๋ค.
์ฌ์ฉ์๊ฐ ์์ฒญํ SQL ๋ฌธ์ฅ์ ์ฒ๋ฆฌํ ๋, EXECUTE ๋จ๊ณ์์ ์ฌ์ฉํ๋ ๋ฉ๋ชจ๋ฆฌ์ด๋ค. ์ค๋ผํด ์๋ฒ๊ฐ ๊ฐ์ฅ ์ต๊ทผ์ ์ฝ๊ฑฐ๋ ๋ณ๊ฒฝํ๊ธฐ ์ํด ์ก์ธ์คํ๋ ๋ฐ์ดํฐ ๋ธ๋ก์ ๋ณต์ฌ๋ณธ์ ์ ์ฅํ๋ ๋ฉ๋ชจ๋ฆฌ์ด๋ค. ๋ธ๋ก์ ๋ณต์ฌ๋ณธ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํด ๋๋ฉด ๋ค์ ๋ฒ์ ํด๋น ๋ธ๋ก ์์ฒญ ์์ ๋์คํฌ I/O๋ฅผ ํ์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ์์ ๋ฐ๋ก ์ฝ๊ฒ ๋์ด ์๋ต ์๋๊ฐ ๋นจ๋ผ์ง๋ค. DB_CACHE_SIZE ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ๋ค.
์ตํฐ๋ง์ด์ ๋ SQL ๋ฌธ์ ๋ํ ์คํ๊ณํ์ ์์ฑํ๋ ์ค๋ผํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ผ๋ถ์ด๋ค. ์คํ๊ณํ์ ๊ฒฐ์ ์ SQL๋ฌธ ์ฒ๋ฆฌ์์ ์ค์ํ ๋จ๊ณ์ด๋ฉฐ ์คํ ์๊ฐ์ ํฐ ์ํฅ์ ์ค ์ ์๋ค. ์คํ๊ณํ์ด๋ ๋ช ๋ น๋ฌธ์ ์คํํ๊ธฐ ์ํด ์์๋๋ก ์ํ๋๋ ์ผ๋ จ์ ์์ ์ ๋งํ๋ค. ์ตํฐ๋ง์ด์ ๋ ์ฟผ๋ฆฌ์์ ์ง์ ๋ ์กฐ๊ฑด๊ณผ ์ฐธ์กฐ๋๋ฐ ๊ฐ์ฒด์ ๊ด๋ จ๋ ๋ค์๊ณผ ๊ฐ์ ๋ง์ ์์๋ค์ ๊ณ ๋ คํ๋ค.
์ค๋ผํด์์ ์ฐธ์กฐํ๊ณ ์๋ ์ตํฐ๋ง์ด์ ์ด๋ค. SQL ๋ฌธ์ฅ์ด ์ฐธ์กฐํ๊ณ ์๋ ๊ฐ์ฒด๋ค์ ๋ํ ์์ง๋ ํต๊ณ ์ ๋ณด์ ๊ฐ๊ณผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋ผ๋ฏธํฐ ์ค์ ๊ฐ์ ๊ธฐ์ด๋ก ๊ฐ์ฅ ์ ์ ๋น์ฉ์ด ๋ฐ์ํ๋ ์คํ๊ณํ์ ๊ฒฐ์ ํ๋ ์ตํฐ๋ง์ด์ ์ด๋ค. ์ฆ ํต๊ณ ์ ๋ณด๋ฅผ ํ์ฉํด SQL ์ํ์ ์์๋ ๋น์ฉ์ ์์ธกํ๊ณ ๊ทธ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ์คํ๊ณํ์ ๊ฒฐ์ ํ๋ ๊ฒ์ด๋ค.
์ตํฐ๋ง์ด์ ๋ ์ฌ์ฉ ๊ฐ๋ฅํ ์ก์ธ์ค ๊ฒฝ๋ก๋ฅผ ๊ธฐ๋ฐ์ผ๋ก SQL๋ฌธ์ ์ ์ฌ์ ๊ณํ ์งํฉ์ ์์ฑํ๋ค. ๋ฐ์ดํฐ ๋ถํฌ ๋ฐ ๋ช ๋ น๋ฌธ์์ ์ก์ธ์คํ ํ ์ด๋ธ๊ณผ ์ธ๋ฑ์ค ์ ์ฅ ์์ญ ํน์ฑ์ ๋ํ ํต๊ณ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ณํ๋ณ ๋น์ฉ์ ์์ธกํ๋ค. ์ฌ๋ฌ ๊ณํ์ ๋น์ฉ์ ๋น๊ตํ๊ณ ์ต์ ๋น์ฉ์ ๊ณํ์ ์ ํํ๊ธฐ ์ํด ์ตํฐ๋ง์ด์ ๋ ํ์ํ๋ค.
WHERE ์ ์์ OR ์ฐ์ฐ์ ์ฌ์ฉ๋ ์ค์ฒฉ๋ ์กฐ๊ฑด์ ์ ์ ๊ฑฐ
SELECT DEPARTMENT_ID, SALARY
FROM EMPLOYEE
WHERE (DEPARTMENT_ID = 10 AND SALARY = 4200)
**OR DEPARTMENT_ID = 10;**
์ง์ ์ฌ์ฉํ์ง ์์ ํ ์ด๋ธ์ SQL์์ ์ญ์
SELECT E.EMPLOYEE_ID, E.LAST_NAME, E.SALARY
FROM EMPLOYEES E, DEPARTMENTS D
WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID
AND E.JOB_ID = 'SH_CLERK';
SELECT E.EMPLOYEE_ID, E.LAST_NAME, E.SALARY
FROM EMPLOYEES E, DEPARTMENTS D
AND E.JOB_ID = 'SH_CLERK';
์กฐ์ธ๊น์ง ํ ํ์๊ฐ ์๋ ๋ช ๋ น์ด์ผ ๊ฒฝ์ฐ (EMPLOYEE ํ ์ด๋ธ์ FK ๋ณด๊ณ ํ์ธ) Single Table Access์ ์คํ ๊ณํ ๋ณด์ฌ ์ค
์๋ธ์ฟผ๋ฆฌ๋ฅผ semi join์ผ๋ก ๋ณํ
SELECT D.DEPARTMENT_ID, D.DEPARTMENT_NAME, D.LOCATION_ID
FROM DEPARTMENTS D
WHERE EXIST (SELECT NULL FROM EMPLOYEE E
WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID)
AND D.LOCATION_ID = 1700;
SELECT D.DEPARTMENT_ID, D.DEPARTMENT_NAME, D.LOCATION_ID
FROM DEPARTMENTS D, EMPLOYEE E
WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID)
AND D.LOCATION_ID = 1700;
์ ํ์ฑ์ 0.0์์ 1.0 ์ฌ์ด์ ๊ฐ์ผ๋ก ํํํ๋ฉฐ ํต๊ณ๊ฐ ์์ ๊ฒฝ์ฐ ๋์ ์ํ๋ง์ ์ฌ์ฉํ๋ฉฐ, ํ์คํ ๊ทธ๋จ์ด ์์ ๊ฒฝ์ฐ ํ ๋ถ์ฐ์ ๊ท ๋ฑํ ๊ฒ์ผ๋ก ๊ฐ์ ํ๊ณ ๊ณ์ฐํ๋ค.
๊ธฐ๋ณธ๊ฐ์ ๊ฐ์ ์ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ต์ ์์ค์ ๋ชป ๋ฏธ์น๋ ๊ณํ์ ์ฌ์ฉํ๊ฒ ๋ ์๋ ์๋ค. ๋ฐ๋ผ์ ์ตํฐ๋ง์ด์ ์ ์์ธก์ ๋์ฑ ์ ํํ๊ฒ ํ๊ธฐ ์ํด ํ์คํ ๊ทธ๋จ ํต๊ณ๊ฐ์ ์ ๊ณตํ์ฌ ์ ํ๋๋ฅผ ๋์ผ ์ ์๋ค.
-- ์ปฌ๋ผ ํต๊ณ
SELECT NUM_DISTINCT, NUM_NULLS, NUM_BUCKETS, HISTOGRAM
FROM DBA_TABLE_COLUMNS
WHERE TABLE_NAME = 'EMPLOYEES'
AND COLUMN_NAME = 'JOB_ID'
AND OWNER = 'HR';
ํต๊ณ ์ ๋ณด ์ ๊ณต์ Autotask์ ์ํด ํต๊ณ๊ฐ ์์ง๋๋ค. ๋งค์ผ ํ ๋ฒ์ฉ ์ค๋ธ์ ํธ ํต๊ณ ์์ง์ด ์ํ๋๋ค. ํต๊ณ ์ ๋ณด๊ฐ ์๊ฑฐ๋ ์์ง ์ดํ 10% ์ด์ ๋ฐ์ดํฐ๊ฐ ๋ณ๋๋ ์ค๋ธ์ ํธ๋ฅผ ๋์์ผ๋ก ์งํ๋๋ค. ํน์ ์๋ ๋ช ๋ น์ด๋ฅผ ํตํด DBMS_STATS ํจํค์ง๋ฅผ ํตํด ์๋์ผ๋ก ์คํํ ์ ์๋ค.
begin
dbms_stats.gather_tables_stats('test', 'cp_emp'); -- test ์คํค๋ง์ cp_emp ํ
์ด๋ธ
end;
ํ ์ด๋ธ์ ์์ฑ๋๋ค๊ณ ํต๊ณ ์์ง์ด ๋ฐ๋ก ๋์ง ์์ง๋ง, ์ธ๋ฑ์ค๋ ์์ฑ๋๋ ์ฆ์ ํต๊ณ ์์ง์ด ๋ฐ๋ก ์ด๋ฃจ์ด์ง๋ค.
์คํ๊ณํ์ ๊ฐ ๋จ๊ณ์ ๊ฒ์ ํ์ ์์ธก ์์ด๋ค. ์กฐ์ธ, ํํฐ ๋ฐ ์ ๋ ฌ ๋น์ฉ์ ๊ฒฐ์ ํ ์ค์ํ ์์น์ด๋ค.
์ตํฐ๋ง์ด์ ๊ฐ ์์ธกํ ๋ช ๋ น์ด๋ฅผ ์คํํ๋ ๋ฐ ํ์ํ ํ์คํ๋ I/O ํ์์ด๋ค. ๋น์ฉ ๊ณต์์ ์ธ ๊ฐ์ง์ ๋ค๋ฅธ ๋น์ฉ ๋จ์๊ฐ ํฌํจ๋๋ค. ๋ง์ฝ ๋น์ฉ์ด 10์ด๋ผ๋ฉด 10๋ฒ์ Single Block I/O๋ฅผ ํ ์๊ฐ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
์ตํฐ๋ง์ด์ ๊ฐ ์คํ ๊ณํ์ ์์ฑํ๊ณ ์์ ์คํ ๊ณํ์ PLAN_TABLE์ ์ ์ฅํ๋ค. ๋ช ๋ น๋ฌธ์ ์ค์ ๋ก ์คํํ์ง๋ ์๋๋ค.
EXPLAIN PLAN FOR select * from employees where employee_id = 100;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3541774394
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 67 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 67 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | EMPLOYEES_IX01 | 1 | | 0 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
| ํญ๋ชฉ | ์ค๋ช |
|---|---|
| ID | ๊ฐ Operation ID |
| Operation | ์คํ๋๋ job |
| Name | Operation์ด ์ก์ธ์คํ๋ ํ ์ด๋ธ, ์ธ๋ฑ์ค |
| Rows | ๊ฐ Operation์ด ๋๋ฌ์ ๋ ๋ฆฌํด๋๋ ๊ฑด์ |
| Cost | ๊ฐ Operation์ Cost |
| Time | ์ํ์๊ฐ |
์คํ ๊ณํ์ด ์ ์ฅ๋๋ ํ ์ด๋ธ์ด๋ฉฐ ์ค๋ผํด์ ์ค์นํ๋ฉด ์๋์ผ๋ก ์์ฑ๋๋ค. ์ด๋ฆ๋ง ๋๊ฐ๊ณ ์ธ์ ๋ง๋ค ๋ค๋ฅธ ํ๋ ํ ์ด๋ธ์ ์ฌ์ฉํ๋ค. ์ฆ ๊ณต์ ๋๋ ํ ์ด๋ธ์ด ์๋๊ธฐ ๋๋ฌธ์ ์ธ์ ๋ง๋ค ๋ ๋ฆฝ์ ์ผ๋ก ์ฌ์ฉํ๋ค.
SELECT OWNER, SYNONYM_NAME, TABLE_OWNER, TABLE_NAME
FROM ALL_SYNONYMS
WHERE SYNONYM_NAME = 'PLAN_TABLE';
OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME
------------------------------ ------------------------------ ------------------------------ ------------------------------
PUBLIC PLAN_TABLE SYS PLAN_TABLE$
EXPLAIN PLAN FOR
SELECT *
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 100;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
Plan hash value: 3541774394
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 67 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 67 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | EMPLOYEES_IX01 | 1 | | 0 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EMPLOYEE_ID"=100)

์ด๋ฐ ์คํ ๊ณํ์ด ์๋ค๋ฉด, 4 โ 3 โ 6 โ 5 โ 2 โ 8 โ 7 โ 1 โ 0 ์์์ด๋ค.
SQL ๋ช ๋ น์ ์์ ์คํ ๊ณํ ๋ฐ ์คํ ํต๊ณ๋ฅผ ์๋์ผ๋ก ์ป์ ์ ์๋ค. AUTOTRACE ON์ด ๋์ด ์์ผ๋ฉด ๋ชจ๋ ๋ช ๋ น์ด๊ฐ ๋ช ๋ ๊ฒฐ๊ณผ, ์คํ ํ๋, ํต๊ณ ์ ๋ณด๊ฐ ์ธํธ๋ก ๋ณด์ฌ์ง๋ค. ์ํ ํต๊ณ๋ V$ ํ ์ด๋ธ์ ์๋ ๋ฐ์ดํฐ๋ค์ ์ฝ์ด์์ ๋ณด์ฌ ์ค๋ค. ์ด๋ด ๊ฒฝ์ฐ DBA์ ๊ถํ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ์ฃผ์ํ์. AUTOTRACE ๊ธฐ๋ฅ์๋ ์ฌ๋ฌ ๊ฐ์ง ๋ช ๋ น ์ต์ ๋ค์ด ์๋ค.
SET AUTOTRACE ON
SELECT *
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 100;
EMPLOYEE_ID FIRST_NAME LAST_NAME
----------- ---------------------------------------- --------------------------------------------------
EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT
-------------------------------------------------- ---------------------------------------- ---------- -------------------- ---------- --------------
MANAGER_ID DEPARTMENT_ID
---------- -------------
100 Steven King
SKING 515.123.4567 2003/06/17 AD_PRES 24000
90
1 row selected.
Elapsed: 00:00:00.01
Execution Plan
----------------------------------------------------------
Plan hash value: 3541774394
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 67 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 67 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | EMPLOYEES_IX01 | 1 | | 0 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("EMPLOYEE_ID"=100)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
2 consistent gets
0 physical reads
0 redo size
1167 bytes sent via SQL*Net to client
512 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
ํต๊ณ์ ๋ํ ํญ๋ชฉ ์ค๋ช ์ ๋ค์๊ณผ ๊ฐ๋ค.
| ํญ๋ชฉ | ์ค๋ช |
|---|---|
| recursive calls | ์ ์ ๋ ๋ฒจ๊ณผ ์์คํ ๋ ๋ฒจ์์ ์์ฑ๋๋ recursive call ์ |
| db block gets | Current ๋ชจ๋๋ก ์ฝ์ ๋ธ๋ก ์ |
| consistent gets | Consistents ๋ชจ๋๋ก ์ฝ์ ๋ธ๋ก ์ |
| physical reads | ๋์คํฌ์์ ์ฝ์ ๋ธ๋ก ์ |
| redo size | ์ด ๋ฆฌ๋ ์ |
| bytes sent via SQL*Net to client | ์๋ฒ ํ๋ก์ธ์ค์์ ํด๋ผ์ด์ธํธ๋ก ๋ณด๋ธ ์ด ๋ฐ์ดํธ ์ |
| bytes received via SQL*Net from client | ์ค๋ผํด๋ท์ ํตํด ํด๋ผ์ด์ธํธ์์ ๋ฐ์ ์ด ๋ฐ์ดํธ ์ |
| SQL*Net roundtrips to/from client | ํด๋ผ์ด์ธํธ๊ฐ ๋ฐํํ fetch all ํ์ |
| sorts (memory) | ๋ฉ๋ชจ๋ฆฌ์์ ์์ ํ ์ํ๋์ด ๋์คํฌ ์ฐ๊ธฐ๊ฐ ํ์ํ์ง ์์ ์ ๋ ฌ ์์ ์ ์ |
| sorts (disk) | ์ต์ํ ํ๋์ ๋์คํฌ ์ฐ๊ธฐ๊ฐ ํ์ํ ์ ๋ ฌ ์์ ์ |
| rows processed | ์กฐํ ๊ฑด์ |
V$SQL_PLAN์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์บ์์ ์๋ SQL ์ปค์์ ์ค์ ๋ก ์ฌ์ฉ๋ ์คํ ๊ณํ์ ์ ๊ณตํ๋ค. ๋ฐ๋ผ์ DBMS_XPLAN.DISPLAY_CURSOR(โsql_idโ, child_number, โformatโ)์ ์ด์ฉํด ์คํ ๊ณํ์ ์ถ๋ ฅํ๋ค.
v$sql ํ ์ด๋ธ์ ์คํํ SQL์ด ๋ชจ๋ ์ ์ฅ๋์ด ์๋ค. ๋ฐ๋ผ์ ์ฌ๊ธฐ์์ ๋ด๊ฐ ์กฐ์ฌํ๊ณ ์ถ์ SQL์ ๊ฒ์ํ ๋ค์ sql_id๋ฅผ ์์๋ด์ผ ํ๋ค.
ํ์ฌ ์ธ์ ์์ ์ง์ ์ ์ํํ SQL์ ๊ฒฝ์ฐ๋ sql_id, child_number๋ฅผ NULL๋ก ์ง์ ํ๊ฑฐ๋ ์๋ต ๊ฐ๋ฅํ๋ค.
-- SQL ID ์ฐพ๊ธฐ
SELECT SQL_ID, SQL_TEXT
FROM v$sql
WHERE SQL_TEXT LIKE '%SELECT E.LAST_NAME, %';
-- ์คํ ๊ณํ ๋ณด์ฌ ์ฃผ๊ธฐ
SELECT *
FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('43tystsdw8hmp'));
์คํ ๊ณํ์ ์ค์ ์ฌ์ฉํ ๊ฒ์ด ๋ง์ง๋ง ํจ๊ป ๋ณด์ฌ ์ฃผ๋ ํต๊ณ๊ฐ์ ์ตํฐ๋ง์ด์ ์ ์์ธก์น๋ค.
V$SQL_PLAN_STATISTICS_ALL์ ๋จ๊ณ๋ณ ์คํ ํต๊ณ๋ฅผ ์ ๊ณตํ๋ค. STATISTIC_LEVEL์ ALL๋ก ์ค์ ํ๊ณ SQL์ ์คํํ ๋ค์ ์ค์ ์ฌ์ฉํ ์คํ ํต๊ณ๋ฅผ ์ ์ ์๋ค. ๋ฐ๋ผ์ ์ด๋ฅผ ํตํด ์ตํฐ๋ง์ด์ ์ ์์ธก์น์ ์ค์ ํต๊ณ๊ฐ ์ผ์นํ์ง ํ์ธ ๋ฐ ๊ฒ์ฆํ ์ ์๋ค.
ALTER SESSION SET STATISTICS_LEVEL=ALL;
SELECT E.LAST_NAME, D.DEPARTMENT_NAME
FROM HR.EMPLOYEES E, HR.DEPARTMENTS D
WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID;
ALTER SESSION SET STATISTICS_LEVEL=TYPICAL;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(null, null, 'ALLSTATS LAST'));
SQL_ID 5bd1y8jpdkm7g, child number 0
-------------------------------------
SELECT E.LAST_NAME, D.DEPARTMENT_NAME FROM HR.EMPLOYEES E,
HR.DEPARTMENTS D WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID
Plan hash value: 1473400139
------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 50 |00:00:00.01 | 8 | 6 | | | |
| 1 | MERGE JOIN | | 1 | 106 | 50 |00:00:00.01 | 8 | 6 | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| DEPARTMENTS | 1 | 27 | 5 |00:00:00.01 | 2 | 2 | | | |
| 3 | INDEX FULL SCAN | DEPT_ID_PK | 1 | 27 | 5 |00:00:00.01 | 1 | 1 | | | |
|* 4 | SORT JOIN | | 5 | 107 | 50 |00:00:00.01 | 6 | 4 | 73728 | 73728 | |
| 5 | VIEW | index$_join$_001 | 1 | 107 | 106 |00:00:00.01 | 6 | 4 | | | |
|* 6 | HASH JOIN | | 1 | | 106 |00:00:00.01 | 6 | 4 | 1096K| 1096K| 1541K (0)|
| 7 | INDEX FAST FULL SCAN | EMP_DEPARTMENT_IX | 1 | 107 | 106 |00:00:00.01 | 3 | 2 | | | |
| 8 | INDEX FAST FULL SCAN | EMP_NAME_IX | 1 | 107 | 107 |00:00:00.01 | 3 | 2 | | | |
------------------------------------------------------------------------------------------------------------------------------------------------
| ํญ๋ชฉ | ์ค๋ช |
|---|---|
| Id | ๊ฐ ๋จ๊ณ ID |
| Operation | ์คํ๋๋ Job |
| Name | ๋จ๊ณ์์ ์ก์ธ์คํ๋ ํ ์ด๋ธ, ์ธ๋ฑ์ค |
| Starts | ๊ฐ ๋จ๊ณ๋ฅผ ๋ฐ๋ณต ์คํํ ํ์ |
| E-Rows | ๊ฐ ๋จ๊ณ์์ ๋ฆฌํดํ๋ ๊ฑด์ (์์) |
| A-Rows | ๊ฐ ๋จ๊ณ์์ ๋ฆฌํดํ๋ ๊ฑด์ (์ค์ ) |
| A-Time | ๊ฐ ๋จ๊ณ๋ณ ์์ ์๊ฐ (๋์ ) |
| Buffers | ๊ฐ ๋จ๊ณ๋ณ ์ฝ์ ์ด ๋ธ๋ก (๋์ ) |
| Reads | ๊ฐ ๋จ๊ณ๋ณ ๋์คํฌ์์ ์ฝ์ ๋ธ๋ก ์ |
| OMem | Opotimal์ผ ๋ ์์๋๋ PGA (๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ์์ ์ฒ๋ฆฌ) |
| 1Mem | One-PASS์ผ ๋ ์์๋๋ PGA (๋์คํฌ ํ ๋ฒ ์ฝ์ด์ด) |
| Used-Mem | ์ค์ ์ฌ์ฉ๋ PGA |
์ผ๋ฐ์ ์ผ๋ก ์ธ์ ๋ ๋ฒจ์์ ํ์ฑํ๋๋ค. ์ธ์ ๋ณ๋ก ๊ทธ๋ฃนํ๋ SQL ๋ฌธ์ ๋ํ ํต๊ณ๋ฅผ ์์งํ๊ณ , tkprof ์ ํธ๋ฆฌํฐ๋ฅผ ์ด์ฉํด ์ฝ๊ธฐ ์ฌ์ด ์ถ๋ ฅ์ ์์ฑํ๋ค. ๋ง์น ํต๊ณ์ ๋ํ ๋ก๊ทธ ํ์ผ์ OS์ ์ ์ฅํ๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค. OS๊ฐ FTP๊ฐ ๊ฐ๋ฅํ ๊ณ์ ์ด์ด์ผ ํ๋ค๋ ์ ์ฝ ์กฐ๊ฑด์ด ์๋ค.
SELECT name, value FROM v$diag_info;
ALTER SESSION SET tracefile_identifier='case1';
exec DBMS_SESSION.SESSION_TRACE_ENABLE(waits=>true);
SELECT * FROM HR.EMPLOYEES WHERE EMPLOYEE_ID = 102;
exec DBMS_SESSION.SESSION_TRACE_DISABLE;
tkprof xe_ora_19216_case1.trc report_1.txt sys=no
type report_1.txt
TKPROF: Release 11.2.0.2.0 - Development on ์ 8์ 18 16:54:27 2025
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Trace file: xe_ora_19216_case1.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
SQL ID: 06m0pgb53b824 Plan Hash: 0
BEGIN DBMS_SESSION.SESSION_TRACE_ENABLE(waits=>true); END;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 0 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 1 100 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1 0.00 0.00 1 100 0 1
Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 48
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 24.21 24.21
********************************************************************************
SQL ID: gmp19j6mx7njy Plan Hash: 1833546154
SELECT *
FROM
HR.EMPLOYEES WHERE EMPLOYEE_ID = 102
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 2 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.00 0.00 0 2 0 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 48
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
1 1 1 TABLE ACCESS BY INDEX ROWID EMPLOYEES (cr=2 pr=0 pw=0 time=6 us cost=1 size=69 card=1)
1 1 1 INDEX UNIQUE SCAN EMP_EMP_ID_PK (cr=1 pr=0 pw=0 time=2 us cost=0 size=0 card=1)(object id 16413)
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 2 0.00 0.00
SQL*Net message from client 2 23.20 23.20
********************************************************************************
SQL ID: 9wuhwhad81d36 Plan Hash: 0
BEGIN DBMS_SESSION.SESSION_TRACE_DISABLE; END;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 0 0 1
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 48
********************************************************************************
OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 2 0.00 0.00 0 0 0 0
Execute 3 0.00 0.00 1 100 0 2
Fetch 2 0.00 0.00 0 2 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 7 0.00 0.01 1 102 0 3
Misses in library cache during parse: 2
Misses in library cache during execute: 1
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
SQL*Net message to client 3 0.00 0.00
SQL*Net message from client 3 24.21 47.42
OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 12 0.00 0.00 0 0 0 0
Execute 199 0.01 0.01 0 0 0 0
Fetch 246 0.00 0.00 0 652 0 1735
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 457 0.01 0.01 0 652 0 1735
Misses in library cache during parse: 10
Misses in library cache during execute: 10
3 user SQL statements in session.
12 internal SQL statements in session.
15 SQL statements in session.
********************************************************************************
Trace file: xe_ora_19216_case1.trc
Trace file compatibility: 11.1.0.7
Sort options: default
1 session in tracefile.
3 user SQL statements in trace file.
12 internal SQL statements in trace file.
15 SQL statements in trace file.
15 unique SQL statements in trace file.
792 lines in trace file.
47 elapsed seconds in trace file.
| ํญ๋ชฉ | ์ค๋ช |
|---|---|
| call | ๋ช ๋ น์ด ์ฒ๋ฆฌ ๋จ๊ณ์ ๋ฐ๋ฅธ ํต๊ณ ์ ๋ณด |
| count | ๊ฐ ๋จ๊ณ๊ฐ ์ํ๋ ํ์ |
| cpu | ์ฒ๋ฆฌ์ ์์๋๋ ์๊ฐ |
| elapsed | ์คํ์ ์์๋๋ ์ด ๊ฒฝ๊ณผ ์๊ฐ |
| disk | ๋ฌผ๋ฆฌ์ ๋ธ๋ก ์ฝ๊ธฐ ์ |
| query | ์ผ๊ด์ฑ ์๋ ๋ชจ๋์์ ๋ ผ๋ฆฌ์ ๋ฒํผ ์ฝ๊ธฐ ์ |
| current | ํ์ฌ ๋ชจ๋์์ ๋ ผ๋ฆฌ์ ๋ฒํผ ์ฝ๊ธฐ ์ |
| rows | fetch, execute์ ์ํด ์ฒ๋ฆฌ๋ ํ ์ |
๋ค์ค ๋ธ๋ก ์ฝ๊ธฐ ์ํ์ผ๋ก High-Water Mark ์๋์ ๋ชจ๋ ๋ธ๋ก์ ์ฝ๋๋ค. ํ ํํฐ๋ง์ด ๊ฐ๋ฅํ๊ณ ๋ง์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ Index Scan๋ณด๋ค ๋น ๋ฅด๋ค. ์ฌ์ฉ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ๋ค.
ROWID๋ฅผ ์ฌ์ฉํ์ฌ ํ๋์ ํ๋ง ๋ฐ๋ก ์ฝ์ด์ค๋ ๋ฐฉ์์ด๋ค. ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๋ ๋ค์๊ณผ ๊ฐ๋ค.
RowID๋ฅผ ์ด์ฉํด์ ๊ฐ์ ์ฐพ์ผ๋ฌ ๊ฐ ๋, ๋ชจ๋ Row์ RowID๋ฅผ ์ธ์ฐ๊ณ ์์ ์๋ ์๋ค. ๊ทธ๋ ๋ค๋ฉด ์ฐพ๊ณ ์ ํ๋ ๋ฐ์ดํฐ์ ๋ํ RowID๋ฅผ ์์์ผ ํ๋๋ฐ, ์ด RowID๋ฅผ ์๊ธฐ ์ํด ์ธ๋ฑ์ค ํ ์ด๋ธ์ ์์์๋ถํฐ ์ญ ํ๋ ๊ฒ ์ญ์ ๋นํจ์จ์ ์ด๋ค. ๋ฐ๋ผ์ B+Tree Index๋ฅผ ์ฌ์ฉํด ์ด์ง ํ์์ ํตํด ์ธ๋ฑ์ค๋ฅผ ์ฐพ๋ ์๋๋ฅผ ๋์ธ๋ค.

๋ฃจํธ ๋ ธ๋์๋ LMC(Left Most Child) ๊ฐ์ ๊ธฐ๋กํ์ฌ ๋ฆฌํ ๋ธ๋ก์ ์ฐพ์๊ฐ๋ ๊ตฌ์กฐ์ด๋ค.
๊ฐ B+ Tree ์ธ๋ฑ์ค์ ๊ฒ์ ์์์ ์ ๋ฃจํธ ๋ธ๋ก์ด๋ค. ํญ๋ชฉ ์์ ๋ฐ๋ผ ์ฌ๋ฌ ๊ฐ์ ๋ถ๊ธฐ ๋ธ๋ก์ผ๋ก ๊ฐ๋ผ์ง๊ณ ์ฌ๊ธฐ์ ๋ค์ ์ฌ๋ฌ ๊ฐ์ ์ตํ์ ๋ธ๋ก๋ค์ด ์๋ค. ์ธ๋ฑ์ค๋ ํญ์ ๊ท ํ์ ์ด๋ฃจ๋ฉฐ ์์์ ์๋๋ก ํ์ฅํ๋ค. ๊ท ํ ์๊ณ ๋ฆฌ์ฆ์ ์ํด B+Tree ๋์ด๊ฐ ๋ถํ์ํ๊ฒ ์ปค์ง ์๋ ์๋๋ฐ, ๊ทธ๋ฐ ๊ฒฝ์ฐ ์ธ๋ฑ์ค๋ฅผ ์ฌ๊ตฌ์ฑํ๋ค.
B+ Tree ์ธ๋ฑ์ค์ ๋ด๋ถ ๊ตฌ์กฐ๋ ์ธ๋ฑ์คํ๋ ์ปฌ๋ผ๊ฐ์ ๋ํ ์ ์ํ ์ก์ธ์ค๋ฅผ ํ์ฉํ๋ค.
์ธ๋ฑ์ค์ root, branch, leaf block๊น์ง ์์ง์ ์ผ๋ก ํ์ํ ํ์ leaf block์์ ํ์ํ ๋ฒ์๋ง ์ํ์ ์ผ๋ก ํ์ํ๋ ๋ฐฉ์์ด๋ค. ๋ฐ๋ผ์ root, branch๋ ์ฒซ ๋ฒ์งธ์ leaf block์ ํ์ํ ๋๋ง ํ ๋ฒ์ฉ ๊ฑฐ์น๊ณ , ์ดํ์๋ leaf block์ ์ํ์ ์ผ๋ก ์ญ ํ๋๋ค.
Single Block Read๋ฅผ ์ํํ๋ฉฐ, ์ฐ๋ฆฌ๊ฐ ์ธ๋ฑ์ค๋ฅผ ์ค์ ํ๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ด์ ๋ ์ด Index Range Scan์ ์งํํ๊ธฐ ์ํด์์ด๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ASC์ผ๋ก ์ ๊ทผํ๋ค. ์์๋ฅผ ์ ๋ฆฌํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
์ธ๋ฑ์ค๋ ์ฌ๋ฌ ๊ฐ์ ์นผ๋ผ์ ๊ฒฐํฉํด์ ๋ง๋ค ์ ์๋ค. ์ต๋ 32๊ฐ์ ์ปฌ๋ผ๊น์ง ํ์ฉํ๋ค. ์ด ์กฐํฉ์ ํ๋ช ํ๊ฒ ํด์ ํ ์ด๋ธ์ ์ก์ธ์ค, ์ธ๋ฑ์ค ์ค์บ ์ต์ํ์ ํ์ฉํ ์ ์๋ค. ์ฐ๋ฆฌ๊ฐ ์ฃผ๋ชฉํด์ผ ํ ๊ฒ์ ์ฒซ ๋ฒ์งธ๋ก Random I/O๋ฅผ ์ค์ด๊ณ , ์ถฉ๋ถํ ์ค์๋ค๋ฉด ์ํ ํ์์ ์ค์ด๋ ๋ฐฉํฅ์ผ๋ก์ ํ๋์ด ํ์ํ๋ค.
์๋ฅผ ๋ค์ด ์๋์ ๊ฐ์ SQL์ ์ํํ๋ค๊ณ ๊ฐ์ ํด ๋ณด์.
SELECT ์ฌ๋ฒ
FROM ์ฌ์
WHERE ์ฌ์๋ช
= '์กฐํฌ์'
AND ์ง๊ธ = '๋ถ์ฅ';
์ธ๋ฑ์ค๊ฐ ์ด๋ฆ์ผ๋ก๋ง ๋์ด ์๋ ์ํ์ผ ๋, ์กฐํฌ์ ๊ณผ์ฅ๊ณผ ์กฐํฌ์ ๋ถ์ฅ์ด ์กด์ฌํ๋ค๋ฉด, ์ธ๋ฑ์ค๋ก ๋ ๊ฐ์ ์กฐํฌ์๋ฅผ ์ฐพ๊ณ ๊ณผ์ฅ๊ณผ ๋ถ์ฅ์ผ๋ก ๋ ๋ฒ์ Random I/O๊ฐ ์ผ์ด๋๋ค. ํ์ง๋ง ์ ์ด์ ์ธ๋ฑ์ค์ (์ฌ์๋ช , ์ง๊ธ)์ผ๋ก ๊ฒฐํฉ ์ธ๋ฑ์ค๋ฅผ ์์ฑํด ๋๋ค๋ฉด, ํ ๋ฒ์ ์กฐํฌ์ ๋ถ์ฅ์ ์ฐพ์์ Random I/O๋ ํ ๋ฒ๋ง ์ผ์ด๋๋ค.
์ด๋ ๊ฒฐํฉ ์ธ๋ฑ์ค์์ ์ธ๋ฑ์ค์ ์ ํ ์ปฌ๋ผ์ด ์กฐ๊ฑด์ ์ ์๊ฑฐ๋ โ=โ ์กฐ๊ฑด์ด ์๋๋ฉด ์ธ๋ฑ์ค ์ค์บ์ ํจ์จ์ฑ์ด ๋ฎ์์ง๋๋ค. ์ฒซ ์ ๋ถ ์กฐ๊ฑด ์ปฌ๋ผ๊น์ง๋ง ์ฐ์์ ์ค์บ์ด ๊ฐ๋ฅํ๋ฏ๋ก ์ดํ ์ปฌ๋ผ์ ๋ํ ์กฐ๊ฑด์ ์ค์บ์ ๋ฒ์๋ฅผ ์ค์ฌ ์ฃผ์ง ๋ชปํ๊ณ FILTER ์กฐ๊ฑด์ผ๋ก๋ง ์ฐธ์ฌํ๊ฒ ๋๋ค. ๋ฐ๋ผ์ ๊ฒฐํฉ ์ธ๋ฑ์ค ์์ฑ์ WHERE ์ ์์ ํญ์ ์ฌ์ฉํ๋ ์ปฌ๋ผ์ด๋ โ=โ ์กฐ๊ฑด์ ๋ง์ด ์ฌ์ฉํ๋ ์ปฌ๋ผ์ ์์ ๋์๋ก ์ข๋ค.
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID b5p87f5czvjh7, child number 0
-------------------------------------
SELECT /*+ index(emp2 emp2_x01) */ * FROM EMP2 WHERE DEPTNO=30 AND
SAL>=2000
Plan hash value: 3451918632
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 8192 |00:00:00.02 | 2339 |
|* 1 | TABLE ACCESS BY INDEX ROWID| EMP2 | 1 | 30492 | 8192 |00:00:00.02 | 2339 |
|* 2 | INDEX RANGE SCAN | EMP2_X01 | 1 | 38229 | 49152 |00:00:00.01 | 238 |
--------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("SAL">=2000)
2 - access("DEPTNO"=30)
21 rows selected.
emp2_x01 ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ ์ค์บ์ ์ธ๋ฑ์ค ์ค์บ์์ 238๋ฒ์ I/O, ๊ทธ๋ฆฌ๊ณ Random I/O๋ฅผ 2000๋ฒ ํ ๊ฒ์ ํ์ธํ ์ ์๋ค.
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 67cz5fd95du3u, child number 0
-------------------------------------
SELECT /*+ index(emp2 emp2_new) */* FROM EMP2 WHERE DEPTNO=30 AND
SAL>=2000
Plan hash value: 2378551592
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 8192 |00:00:00.01 | 854 | 22 |
| 1 | TABLE ACCESS BY INDEX ROWID| EMP2 | 1 | 30492 | 8192 |00:00:00.01 | 854 | 22 |
|* 2 | INDEX RANGE SCAN | EMP2_NEW | 1 | 30492 | 8192 |00:00:00.01 | 104 | 22 |
-----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("DEPTNO"=30 AND "SAL">=2000 AND "SAL" IS NOT NULL)
20 rows selected.
์ด๋ INDEX(DEPTNO, SAL)์ ์๋ก ์ค์ ํด ํ๋ํด ์ฃผ๋ฉด, ์ธ๋ฑ์ค ์ค์บ์์ 104๋ฒ์ผ๋ก ๊ฑฐ๋ฅผ ์ ์์ผ๋ฉฐ, Random I/O๊ฐ 850๋ฒ์ผ๋ก ํ ์ค์ด๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๋ํ ์ด๋ฏธ ์ธ๋ฑ์ค์ SAL ์นผ๋ผ์ด ๋ฐ์๋์ด ์๊ธฐ ๋๋ฌธ์ ์ธ๋ฑ์ค ์ค์บ ์ดํ ๋ฐ๋ก FILTERING์ด ๋ถํ์ํ๋ค.
QUERY์ ๊ฐ์ ๊ฐ์ง IN์ ์ด๋ ๋์ผํ ์ด์ ๋ฑ์ ์ ์ด๊ฐ OR๋ก ์ฐ๊ฒฐ๋์ด ์์ ๋ ์ฌ์ฉ๋๋ค. INLIST ITERATOR๋ ์ด๊ฑฐ๋ ๊ฐ๋ค์ ๋ณ๋๋ก ์คํํ๋ค. ์คํ ๊ณํ์ ๋ฑ์ ์ ์ ๊ฐ์ง ๋ช ๋ น๋ฌธ์ ๊ฒฐ๊ณผ์ ๋์ผํ๋ฉฐ ๋จ๊ณ๊ฐ ํ๋ ์ถ๊ฐ๋๋ค.
์ตํฐ๋ง์ด์ ๋ IN์ ์ ๊ฐ์ด ์ง์ ๋ ๋ INLIST ITERATOR๋ฅผ ์ฌ์ฉํ๊ณ , ํด๋น ์ด์ ๋ํ ์ ํ์ ์ธ๋ฑ์ค๋ฅผ ์ฐพ๋๋ค. ๋์ผํ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ OR ์ ์ด ์๋ ๊ฒฝ์ฐ ์ตํฐ๋ง์ด์ ๋ ์ด ์ฐ์ฐ์ ์ ํํ๋ค. IN ์ฐ์ฐ์๋ก ์์ฑํ ๊ฐ์ด ๋งค์ฐ ๋ง๊ณ ์ด๋ฏธ ๊ฐ๊น์ด ์๋ ๊ทผ์ ๊ฐ์ด๋ผ๋ฉด ์ธ๋ฑ์ค๋ฅผ ๊ฐ๊ฐ ํ๋ ๊ฒ๋ณด๋ค ๋ฒ์ ์ ํ ํ ํํฐ๋งํ๋ ๊ฒ์ด ๋ ๋์ ์๋ ์๋ค. IN ์ฐ์ฐ์๋ ๊ฐ๋ค์ด ์ฌ๊ธฐ์ ๊ธฐ ํฉ์ด์ ธ ์์ ๊ฒฝ์ฐ ๋ฒ์ ์ค์บ์ ๋น์ฉ์ ์ค์ด๊ธฐ ์ํด ์ ํํ๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
๋ชจ๋ leaf block์ logical ์์๋๋ก ์ฝ๋ ๊ฒ์ด๋ค. ์ธ๋ฑ์ค ์ปฌ๋ผ ์ด์ธ์ ์ปฌ๋ผ ์กฐํ ์์๋ ์ฌ์ฉ๋ ์ ์์ผ๋ฉฐ, ์ฌ์ฉ๋๋ ์ปฌ๋ผ์ NOT NULL ์ ์ฝ ์กฐ๊ฑด ๋๋ ์กฐ๊ฑด์์ด ํ์ํ๋ค. Left Most Child๋ฅผ ์ฐพ๊ธฐ ์ํด Root์ Branch๋ฅผ ํ ๋ฒ์ฉ ๋ฐฉ๋ฌธํ๋ค. Multi Block์ด ์๋ ์ฐจ๋ก์ฐจ๋ก๋ก ์ฝ์ด ์ค๋ ๋ฐฉ์์ด๋ค. ์ธ๋ฑ์ค์ ๋ฐ๋ผ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ค์ด ๋ฌผ๋ฆฌ์ ์ผ๋ก ์์ ์์ง ์๊ธฐ ๋๋ฌธ์, ๋ ผ๋ฆฌ์ ์ธ B+ Tree ๊ตฌ์กฐ์ ๋ฐ๋ผ ๋๊ฐ์ด ROWID๋ฅผ ์ฐพ์ ๋ถ๋ฌ์ค๋ ํ์์ด๋ค. ๋ฐ๋ผ์ Single Block I/O๋ฅผ ์คํํ๋ค. ๋ณดํต Full Table Scan ๋์ ํน์ SORT ๋์ ์ผ๋ก ์ฌ์ฉํ๋ค.
๋ชจ๋ Leaf Block์ ์ฝ๋๋ค. ์ธ๋ฑ์ค์ ํฌํจ๋ ์ปฌ๋ผ์ผ๋ก๋ง ์กฐํํ ๋ ์ฌ์ฉํ๋ค. ์ด๊ฒ ์ญ์ ์ฌ์ฉ๋๋ ์นผ๋ผ์ NOT NULL ์ ์ฝ ์กฐ๊ฑด ๋๋ ์กฐ๊ฑด์์ด ํ์ํ๊ณ , Multi Block Read๋ฅผ ์ํํ๊ธฐ ๋๋ฌธ์ ๋น ๋ฅธ ์ฝ๊ธฐ๊ฐ ๊ฐ๋ฅํด์ง๋ค. ๋ณ๋ ฌ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๊ณ , ๋์ ๋ฒ์์ ๊ฒ์์์ ์ฌ์ฉ๋๋ค.
์ธ๋ฑ์ค๋ผ๋ฆฌ ์กฐ์ธ๋๋ ํํ์ด๋ฉฐ SELECT ์ ๊ณผ WHERE ์ ์นผ๋ผ์ด ๋ชจ๋ ์ธ๋ฑ์ค์ ์กด์ฌํด์ผ ์ฌ์ฉํ ์ ์๋ค. ํ ์ด๋ธ์ ์ ๊ทผ ์์ด ์ธ๋ฑ์ค๋ง ์ด์ฉ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ์ฌ์ฉ๋๋ค. HASH JOIN์ ํํ๋ก ๋์ํ๋ค. ROWID๊ฐ ๊ฐ์ ๋ฐ์ดํฐ๋ค๋ผ๋ฆฌ JOINํ๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค.
SORT ORDER BY ์คํ ๋จ๊ณ๋ Sort Area๋ฅผ ํ ๋นํ์ฌ ์ ๋ ฌ ์์ ์ ์ํํ๋ค. ์ ๋ ฌ ์ํ๋ฅผ ์ด๋ฏธ ๊ฐ์ง๊ณ ์๋ ์ธ๋ฑ์ค๊ฐ ์๋ค๋ฉด, ๋ณ๋์ ์ ๋ ฌ ์์ ์ํ ์์ด ๊ทธ๋ฅ ๊ฒ์ํ ์ ์๋ค. ๋ฐ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ์ ์ ํ๊ฒ ํ์ฉํ๋ฉด ์ ๋ ฌํ๋ ์์ ์ ๋ํ ํฐ ์ด๋์ ๋ณผ ์ ์๋ค. ํ์ง๋ง ์ ๋ ฌ์ ์ํํ๋ ๊ฒ์ด ๋ ๋์ ๊ฒฝ์ฐ๋ ์๊ธฐ ๋๋ฌธ์ ์ฃผ์ ๊น๊ฒ ์ฌ์ฉํด์ผ ํ๋ค.
์ด๋ ์กฐ๊ฑด์ ์ ์ด์ฉํ์ฌ NOT NULL์ธ ๊ฐ๋ค๋ง ์ก์ธ์คํ๋๋ก ํด์ผ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ ์ ๋ ฌ ์์ ์ ์ํํ ์ ์๋ค. ๊ทธ๋ฅ ์ ๋ ฌ์ ํ ๋๋ NULL ๊ฐ์ ๊ฐ์ฅ ํฐ ๊ฐ์ด๋ผ๊ณ ๊ฐ์ ํ๊ณ ์ ๋ ฌํ๋ค. ํ์ง๋ง B+ Tree Index์๋ NULL ๊ฐ์ด ์ ๋ค์ด๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ ์ ๋ ฌ์ ํ ๋๋ ์ฃผ์ํด์ผ ํ๋ค. ๋ํ ๊ธฐ์กด์ ์ ๋ ฌ ์์ ์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฌํด์ผ ํด์ ๋ถ๋ถ ๋ฒ์ ์ฒ๋ฆฌ๊ฐ ๋ถ๊ฐ๋ฅํ์ง๋ง, ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๋ ฌ ์์ ์์ฒด๊ฐ ์๋ต๋๊ธฐ ๋๋ฌธ์ ๋ถ๋ถ ๋ฒ์ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ์ ์ ์ ๋ ๋์ฑ ๋น ๋ฅด๊ฒ ์๋ต์ ๋ฐ์ ๋ณผ ์ ์๋ค.
Outer Table ํ์ ์์ค๋ฅผ ์ค์บํ๋ ๊ฒ์ด๋ค. Outer Table์ ๊ฐ ํ์ ๋ํด ์กฐ์ธ ์กฐ๊ฑด์ ๋ง์กฑํ๋ Inner Table์ ๋ชจ๋ ํ์ ๊ฒ์ํ๋ ๊ฒ์ด๋ค. Outer Table ๊ฒ์ ์กฐ๊ฑด์ ํ์ด ์ ์ ๊ฒฝ์ฐ์ ์ ํฉํ๊ณ ์กฐ์ธ์ ์ฐธ์ฌํ๋ ํ ์ด๋ธ์ ์์๊ฐ ์ค์ํ๋ค.
Nested Loops Join์ ์ ํ ํ ์ด๋ธ (Outer Table - driving) ๊ฒฐ์ ํ ํํ ํ ์ด๋ธ (Inner Table - driven)์ ๋ฐ๋ณต์ ์ผ๋ก ์ ๊ทผํ๋ค. ํํ ํ ์ด๋ธ์ ์กฐ์ธ ์ปฌ๋ผ์ ์ธ๋ฑ์ค๊ฐ ํ์ํ๊ณ , ์๋์ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ธํ๋ OLTP ์ ๋ฌด ํ๊ฒฝ์ ์ ํฉํ๋ค. ํ ๋ ์ฝ๋์ฉ ์์ฐจ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ถ๋ถ ๋ฒ์ ์ฒ๋ฆฌ์ ์ต์ ํ๋์ด ์๋ค. ๋ง์ ์์ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ธํ ๋ Random Access ํ์๊ฐ ๋์์ง๋ค. ๋ฐ๋ผ์ Nested Loops Join์ ํ๋ ํฌ์ธํธ๋ Index ํ๋ ํฌ์ธํธ๋ ๋์ผํ๋ค.
์ ํ, ํํ ํ ์ด๋ธ์ ๊ฒฐ์ ํ๋ ์กฐ๊ฑด์ ๋ค์๊ณผ ๊ฐ๋ค.
์คํ ๊ณํ์์๋ Outer Table - Inner Table ์์๋ก ๋์จ๋ค.
๋ง์ฝ ์กฐ์ธํ๋ ค๋ ๋ฐ์ดํฐ๊ฐ ๋ฒํผ ์บ์์ ์์ผ๋ฉด ๊ณ์ํด์ ๋ฌผ๋ฆฌ์ ์ฝ๊ธฐ๋ฅผ ์๋ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์๋ฒ๊ฐ I/O ์๋ต์ ์ป์ ๋๊น์ง Sleepํด์ผ ํ๋ ์๊ฐ์ด ๋ง๋ค. ๋ฐ๋ผ์ ์ผ๋จ ๋ฒํผ ์บ์์ ์๋ ๋ฐ์ดํฐ๋ผ๋ฆฌ๋ง ์ผ๋จ JOIN์ ํ๊ณ , ๋ฒํผ ์บ์์ ์์ด์ ์กฐ์ธ์ ๋ณด๋ฅํ ๋ฐ์ดํฐ๋ค์ ๋ชจ์๋ค๊ฐ ํ ๋ฒ์ ๋ฌผ๋ฆฌ์ ์ฝ๊ธฐ๋ฅผ ์๋ํ๋ ๊ฒ์ด NLJ Batching์ด๋ค.
์ฒซ ๋ฒ์งธ์ ๋ ๋ฒ์งธ ํ ์์ค๊ฐ ๋์ผํ ์ ๋ ฌ ํค๋ก ์ ๋ ฌ๋๊ณ , ์ ์ชฝ์์ ์ ๋ ฌ๋ ํ์ด ๋ณํฉ๋๋ ๊ฒ์ด๋ค. ์์ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
ํฉ๋ณํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์กฐ์ธ ์์ ์ด ์๋ฃ๋๊ธฐ๊น์ง ๋ถ๋ถ ๋ฒ์ ์ฒ๋ฆฌ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค. ์์ชฝ ๋ชจ๋ ์ ๋ ฌ์ด ๋๋์ผ์ง๋ง ์กฐ์ธ์ด ๋ง๋ค์ด์ง๊ธฐ ๋๋ฌธ์ด๋ค. ์ ์ฉ์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ธ PGA์์ ์ํ๋๊ธฐ ๋๋ฌธ์ ์๋๊ฐ ๋น ๋ฅด๋, ์ถฉ๋ถํ ๋ฉ๋ชจ๋ฆฌ ํ๋ณด๊ฐ ์ด๋ฃจ์ด์ง์ง ์์ผ๋ฉด ์์ ํ ์ด๋ธ ์คํ์ด์ค๋ฅผ ํ์ฉํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ์ ํ์ ์์ธ์ด ๋ ์๋ ์๋ค. ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ์ด ์กฐ์ธ์ด ๋ง์ด ํ์ฉ๋ ๋๋, ์ด๋ฏธ ์ธ๋ฑ์ค๊ฐ ์์ด์ SORT ์์ด MERGE๋ง ํด๋ ๋ ๋ ์ ํ๋ ์ ์๋ค. ๋ ๋ค ์ ๋ ฌํ๊ณ ์กฐ์ธํ๋ ๊ฒฝ์ฐ๋ ๋์ฉ๋ DB์์๋ ๊ฑฐ์ ๋ณผ ์ ์๋ค.
์์ ํ ์์ค (Build Table)๋ฅผ ์ฌ์ฉํ์ฌ ํด์ ๋งต์ ์์ฑํ๋ค. ๋ ๋ฒ์จฐ ํ ์์ค (Probe Table)์ด ํด์ฑ ์ฒ๋ฆฌ๋์ด ํด์ ๋งต์ ๋ํด ๊ฒ์ฌํ๋ค. ์์ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
์ด๋ ํด์๋ฐ์ดํฐ๋ฅผ ํ์ฉํ ์กฐ์ธ์ด๊ธฐ ๋๋ฌธ์ = ์กฐ์ธ์์๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ณ , ์ ์ฒด ๋ฒ์ ์ฒ๋ฆฌ์ ์ต์ ํ๋์ด ์๋ค. ์๋์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ๋ ์ฐ์ธ๋ค๋ฉด ๋ถํ์ํ I/O๊ฐ ์ฆ๊ฐํ์ฌ ์คํ๋ ค ๋นํจ์จ์ ์ผ ์ ์๋ค. Hash Join์ ๋๋์ ์กฐ์ธ์ ์ํํ ๋ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ ๊ฐ๊ธ์ ์ผ๋ก Multi Block I/O๋ฅผ ์ง์ํ๋ ์ก์ธ์ค ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค. ์กฐ์ธ ์์์ ๋ฐ๋ผ I/O์ ๋ณํ๋ ์์ผ๋ ์ฌ์ฉ๋ ๋ฉ๋ชจ๋ฆฌ์ ํฌ๊ธฐ๊ฐ ๋์ ๋๊ฒ ์ฆ๊ฐ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๋ฐ์ดํฐ๊ฐ ๋ ๋ง์ ์งํฉ์ ๋จผ์ ์ก์ธ์คํ์ฌ Hash Map์ ์์ฑํ๋ ค๋ฉด ๊ทธ์ ๋ฐ๋ฅธ ๋ถ๋ด์ด ๋ ์ปค์ง ์๋ ์๊ธฐ ๋๋ฌธ์ ํ์ด ์์ ํ ์ด๋ธ์ Build Table๋ก ์ผ๋๋ค.