λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
ORACLE/Tunning

[Oracle] Index 탐색 방식 - Unique,Range,Full,Fast,Skip

by πŸŒ»β™š 2020. 10. 5.

Index

μΈλ±μŠ€λŠ” ν…Œμ΄λΈ”μ— λŒ€ν•œ λ™μž‘ 속도λ₯Ό λ†’νžˆκΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” μ˜€λΈŒμ νŠΈμž…λ‹ˆλ‹€. μ •λ ¬λœ μƒνƒœλ‘œ 데이터가 μ €μž₯λ˜μ–΄ λΉ λ₯Έ μ†λ„λ‘œ μ›ν•˜λŠ” 데이터에 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ, 인덱슀λ₯Ό μ‚¬μš©ν•œλ‹€κ³  ν•΄μ„œ 무쑰건 속도가 λΉ λ₯Έ 것은 μ•„λ‹™λ‹ˆλ‹€. ν…Œμ΄λΈ”μ˜ 전체 데이터λ₯Ό 좜λ ₯ν•˜λŠ” κ²½μš°μ—λŠ” 인덱슀의 νƒμƒ‰λ³΄λ‹€λŠ” ν…Œμ΄λΈ”μ„ 전체 νƒμƒ‰ν•˜λŠ”κ²ƒμ΄ λΉ λ¦…λ‹ˆλ‹€. κ·Έλž˜μ„œ 주둜 νƒμƒ‰ν•˜λŠ” 데이터가 λ§Žμ€λ° λ°˜ν™˜λ˜λŠ” 데이터가 적은 경우 인덱슀λ₯Ό μ‚¬μš©ν•˜κ²Œ λ©λ‹ˆλ‹€. 이런 인덱슀λ₯Ό μ‚¬μš©ν• λ•Œ μ˜΅ν‹°λ§ˆμ΄μ €λŠ” κ°€μ • μ΅œμ ν™”λœ λ°©λ²•μœΌλ‘œ 탐색을 ν•©λ‹ˆλ‹€. μΈλ±μŠ€μ—λŠ” μ•„λž˜μ˜ 탐색 방식이 있고 ν•˜λ‚˜μ”© μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

  • Index Unique Scan
  • Index Range Scan
  • Index Full Scan
  • Index Fast Full Scan
  • Index Skip Scan

 

μ‹€μŠ΅ν™˜κ²½

OS : Red Hat Enterprise Linux Server release 6.10
DB : Oracle 11.2.0.1
SID : orcl
user : jamong

 

ν…Œμ΄λΈ” ꡬ쑰

SYS@orcl> create table jamong.departments as select * from hr.departments;
SYS@orcl> create table jamong.employees as select * from hr.employees;
SYS@orcl> alter table jamong.departments add constraint pk_departments primary key(department_id);
SYS@orcl> alter table jamong.employees add constraint pk_employees primary key(employee_id);

JAMONG@orcl> alter session set statistics_level=all;

HR κ³„μ •μ˜ κΈ°λ³Έ ν…Œμ΄λΈ”μ˜ 데이터λ₯Ό  jamong κ³„μ •μœΌλ‘œ μ΄λ™ν•˜μ—¬ μ‚¬μš©ν–ˆκ³ , μ»€μ„œμ— μ‘΄μž¬ν•˜λŠ” μ‹€ν–‰κ³„νšμ„ μˆ˜μ‹œλ‘œ ν™•μΈν•˜κΈ° μœ„ν•΄ statistics_level을 all둜 μ„€μ •ν–ˆμŠ΅λ‹ˆλ‹€.

 

xplan.sql

set linesize 150
set pagesize 100

select * from table(dbms_xplan.display_cursor(null,null,'allstats last cost'));

μ‹€ν–‰ κ³„νšμ— λŒ€ν•œ 상세 λ‚΄μš©μ€ μ•„λž˜ κΈ€μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

[Oracle] μ‹€ν–‰κ³„νš 확인 방법 XPLAN, AutoTrace, SQL Trace

μ‹€ν–‰κ³„νš μ•Œκ³ λ¦¬μ¦˜ 문제 ν’€λ•Œλ₯Ό λ– μ˜¬λ €λ΄…μ‹œλ‹€. 문제λ₯Ό 읽고 μ–΄λ–€ λ°©μ‹μœΌλ‘œ ν’€μ–΄μ•Ό 정확도와 νš¨μœ¨μ„±μ„ μž‘μ„ 수 μžˆμ„μ§€ κ³ λ―Όν•©λ‹ˆλ‹€. 완전탐색을 ν•΄μ•Όν•˜λŠ”μ§€, μ΄λΆ„νƒμœΌλ‘œ μ‹œκ°„λ³΅μž‘λ„λ₯Ό 쀄일 수 있

myjamong.tistory.com

 

 

1. Index Unique Scan

Index Unique Scan은 결과둜 ν•˜λ‚˜μ˜ 건이 λ°˜ν™˜λ λ•Œ μ‚¬μš©λ˜κ³  칼럼이 μœ μΌν•œ κ°’μœΌλ‘œ κ΅¬μ„±λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. 즉 Primary Key에 기본적으둜 μƒμ„±λ˜λŠ” μΈλ±μŠ€μž…λ‹ˆλ‹€. 쑰건 검색이 단일(=)인 경우 μ‚¬μš©ν•˜κ²Œλ©λ‹ˆλ‹€.

 

μ˜ˆμ‹œ

JAMONG@orcl> 
select 
    employee_id
    ,first_name
    ,last_name
    ,salary 
from employees 
where employee_id = 100;

JAMONG@orcl> @xplan

INDEX UNIQUE SCAN을 톡해 ν•˜λ‚˜μ˜ κ°’λ§Œ λ°›μ•„μ„œ μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— 인덱슀 μƒμ—μ„œ ν•˜λ‚˜μ˜ 블둝을 읽고 ν…Œμ΄λΈ”μ— μ ‘κ·Όν•˜μ—¬ ν•˜λ‚˜μ˜ 블둝을 읽어 총 2번의 논리적 블둝 읽기λ₯Ό ν–ˆμŠ΅λ‹ˆλ‹€.

 

νŠΉμ§•

  • 칼럼의 값이 μœ μΌν•œ Primary Key에 μ‚¬μš©λœ Index
  • 동등 쑰건 "="
  • Single Block

 

2. Index Range Scan

Index Range Scan은 κ°€μž₯ 일반적인 Index의 탐색 λ°©μ‹μž…λ‹ˆλ‹€. Indexλ₯Ό 수직 탐색 ν›„ ν•„μš”ν•œ λ²”μœ„κΉŒμ§€λ§Œ 탐색은 ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€. 인덱슀의 λ°μ΄ν„°λŠ” μ •λ ¬λœ μƒνƒœλ‘œ μ €μž₯이 λ˜λ―€λ‘œ λ²”μœ„μ— λŒ€ν•œ 탐색이 ν•„μš”ν• λ•Œ 효율적으둜 데이터λ₯Ό 탐색할 수 있으며 리프 λΈ”λ‘μ—μ„œ λ‹€μŒ λ¦¬ν”„λΈ”λ‘μ˜ 정보λ₯Ό κ°–κ³  μžˆμ–΄ λ‹€μ‹œ 브랜치 블둝을 읽을 ν•„μš”μ—†μ΄ λ‹€μŒ 데이터λ₯Ό λ°”λ‘œ 읽을 수 μžˆμŠ΅λ‹ˆλ‹€. 이런 νŠΉμ§•μ„ 잘 ν™œμš©ν•˜λ©΄ μ •λ ¬μž‘μ—…μ„ μƒλž΅ν•˜κ±°λ‚˜ μ΅œλŒ€κ°’, μ΅œμ†Ÿκ°’μ„ μ°ΎλŠ”λ° μœ μš©ν•˜κ²Œ ν™œμš©λ  수 μžˆμŠ΅λ‹ˆλ‹€.

 

μ˜ˆμ‹œ

JAMONG@orcl> create index employees_dept_idx on employees(department_id);
JAMONG@orcl> 
select 
    employee_id
    ,first_name
    ,last_name
    ,department_id
    ,salary 
from employees 
where department_id > 80 
order by department_id;

JAMONG@orcl> @xplan

department_id 칼럼으둜 인덱슀λ₯Ό μƒμ„±ν•˜κ³  Index Range Scan을 μ‚¬μš©ν•˜λŠ” μ˜ˆμ‹œλ₯Ό ν™•μΈν•΄λ΄€μŠ΅λ‹ˆλ‹€. 쿼리상에 department_id둜 μ •λ ¬ν•˜λŠ” μž‘μ—…μ„ μš”μ²­ν•˜λŠ”λ° μΈλ±μŠ€μžμ²΄κ°€ μ •λ ¬λœμƒνƒœλ‘œ μ €μž₯λ˜μ–΄μžˆμ–΄ λ”°λ‘œ μ •λ ¬μž‘μ—…μ„ ν•˜μ§€ μ•ŠλŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

JAMONG@orcl> 
select 
    employee_id
    ,first_name
    ,last_name
    ,department_id
    ,salary 
from employees 
where department_id > 80 
order by department_id desc;

JAMONG@orcl> @xplan

λ˜‘κ°™μ€ 쿼리λ₯Ό λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ μ •λ ¬ν–ˆμ„ λ•Œμ˜ μ‹€ν–‰κ³„νšμž…λ‹ˆλ‹€. Index Range Scan을 μ§„ν–‰ν•˜λŠ”λ° Descending으둜 νƒμƒ‰ν•˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” μ˜€λ¦„μ°¨μˆœμœΌλ‘œ μ •λ ¬λ˜μ–΄ μžˆλŠ” 인덱슀λ₯Ό μ•žμ—μ„œλΆ€ν„°κ°€ μ•„λ‹Œ λ’€μ—μ„œλΆ€ν„° νƒμƒ‰ν•˜μ—¬ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

 

μ²˜μŒλΆ€ν„° μΈλ±μŠ€μ— 데이터λ₯Ό λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ μ €μž₯ν•˜λŠ” descending indexλ₯Ό μƒμ„±ν•˜λŠ” 방법도 μžˆμŠ΅λ‹ˆλ‹€.

JAMONG@orcl> drop index employees_dept_idx;
JAMONG@orcl> create index employees_dept_idx on employees(department_id desc);
JAMONG@orcl> 
select 
    employee_id
    ,first_name
    ,last_name
    ,department_id
    ,salary 
from employees 
where department_id > 80 
order by department_id desc;

JAMONG@orcl> @xplan

데이터가 λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ μΈλ±μŠ€μ— μ €μž₯λ˜μ–΄μžˆμ–΄ λ‚΄λ¦Όμ°¨μˆœ κ²°κ³Όλ₯Ό μš”μ²­ν• λ•Œ 일반 Index Range Scan을 ν•©λ‹ˆλ‹€. Descending Index Range Scan은 μ΅œλŒ€κ°’μ„ κ΅¬ν• λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€. max 값을 κ΅¬ν• λ•Œ μΈλ±μŠ€λ‘œλΆ€ν„° κ°€μž₯ 끝에 μžˆλŠ” ν–‰ ν•˜λ‚˜λ§Œ μ½μ–΄μ˜€λ©΄ λ˜κΈ°λ•Œλ¬Έμ— 전체 데이터λ₯Ό 탐색할 ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. λ§Œμ•½ μ˜΅ν‹°λ§ˆμ΄μ €κ°€ λ‹€λ₯Έ 선택을 ν•œλ‹€λ©΄ 힌트λ₯Ό μ‚¬μš©ν•΄μ„œ ν•˜λ‚˜μ˜ ν–‰λ§Œ 읽도둝 μœ λ„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

νŠΉμ§•

  • 비ꡐ쑰건(>,<) μ‚¬μš© μ‹œ --> Unique Index
  • Non Unique Index μ‚¬μš©μ‹œ μ‚¬μš©λ  수 있음
  • 수직 탐색 ν›„ ν•„μš”ν•œ λ²”μœ„κΉŒμ§€λ§Œ 탐색
  • Single Block Read

 

3. Index Full Scan

Index Full Scan은 첫번째 λ¦¬ν”„λΈ”λ‘κΉŒμ§€ 수직적 탐색 ν›„, 인덱슀 전체λ₯Ό νƒμƒ‰ν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€. 주둜 ν…Œμ΄λΈ”μ—μ„œ Table Full Scan의 뢀담이 ν¬κ±°λ‚˜ μ •λ ¬μž‘μ—…μ„ μƒλž΅ν•˜κΈ° μœ„ν•΄ ν…Œμ΄λΈ” 전체λ₯Ό νƒμƒ‰ν•˜λŠ” 것보닀 Indexλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μœ λ¦¬ν•©λ‹ˆλ‹€. 그런데 이 방법은 μƒμ„±λœ μΈλ±μŠ€κ°€ μ—†μ–΄ μ‚¬μš©λœ λ°©λ²•μœΌλ‘œ Index Range Scan으둜 μœ λ„ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

 

μ˜ˆμ‹œ

JAMONG@orcl> drop index employees_dept_idx;
JAMONG@orcl> create index employees_dept_idx on employees(department_id);

JAMONG@orcl> 
select 
    * 
from employees 
where department_id is not null
order by department_id;

JAMONG@orcl> @xplan

department_id에 λ‹€μ‹œ 인덱슀λ₯Ό μƒμ„±ν–ˆμŠ΅λ‹ˆλ‹€. μš°μ„  μ‘°κ±΄μ ˆμ— range scan을 ν”Όν•˜κΈ° μœ„ν•΄ is not null 쑰건을 λΆ€μ—¬ν–ˆμŠ΅λ‹ˆλ‹€. 그리고 department_idλ₯Ό κΈ°μ€€μœΌλ‘œ μ •λ ¬ν•˜λŠ” μž‘μ—…μ„ ν–ˆμŠ΅λ‹ˆλ‹€. 이번 μ˜ˆμ‹œλŠ” μ •λ ¬μž‘μ—…μ„ μƒλž΅ν•˜κΈ° μœ„ν•΄ Index Full Scan을 μ‚¬μš©ν•œ 것 μž…λ‹ˆλ‹€. is not null 쑰건이 μ•„λ‹ˆλ”λΌλ„ Full Scan을 μ‚¬μš©ν•  순 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ 이번 μ˜ˆμ‹œμ—μ„œλŠ” 단일 칼럼 인덱슀λ₯Ό μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— 쑰건을 λΆ€μ—¬ν•˜λ©΄ Range Scan으둜 νƒμƒ‰ν•˜κΈ° λ•Œλ¬Έμ— not null 쑰건을 μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€. 이런 μ‹μœΌλ‘œ μ •λ ¬μž‘μ—…μ„ μƒλž΅ν•˜κΈ° μœ„ν•΄ 많이 μ‚¬μš©λ©λ‹ˆλ‹€.

 

JAMONG@orcl> select count(*) from employees;
JAMONG@orcl> @xplan

count ν•¨μˆ˜λ₯Ό μ‚¬μš©ν• λ•Œλ„ Index Full Scan을 μ‚¬μš©ν•©λ‹ˆλ‹€. μš°μ„  쑰건절이 μ—†λŠ”λ°λ„ λΆˆκ³ ν•˜κ³  Indexλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. count ν•¨μˆ˜λŠ” ν…Œμ΄λΈ” μ•‘μ„ΈμŠ€λ₯Ό ν•  ν•„μš”μ—†μ΄ μΈλ±μŠ€λ§ŒμœΌλ‘œλ„ Count값을 λ°›μ•„μ˜¬ 수 μžˆμŠ΅λ‹ˆλ‹€. 데이터 전체가 μžˆλŠ” ν…Œμ΄λΈ”μ— λΉ„ν•΄μ„œ μΈλ±μŠ€μ— μ €μž₯λ˜μ–΄ μžˆλŠ” λ°μ΄ν„°λŠ” 일뢀 μΉΌλŸΌμž…λ‹ˆλ‹€. κ·Έλž˜μ„œ λŒ€λΆ€λΆ„ μΈλ±μŠ€κ°€ μ°¨μ§€ν•˜λŠ” λ°μ΄ν„°μ˜ 곡간이 ν…Œμ΄λΈ”λ³΄λ‹€ 훨씬 적기 λ•Œλ¬Έμ— ν…Œμ΄λΈ” 전체보닀 인덱슀 전체λ₯Ό νƒμƒ‰ν•˜λŠ” λΉ„μš©μ΄ μ μŠ΅λ‹ˆλ‹€.

 

JAMONG@orcl> select max(department_id) from employees;
JAMONG@orcl> @xplan

JAMONG@orcl> select min(department_id) from employees;
JAMONG@orcl> @xplan

λ‹€μŒ Index Full Scan을 κ°€μž₯ 많이 μ‚¬μš©ν•˜λŠ” 뢀뢄이 max와 minν•¨μˆ˜λ₯Ό μ‚¬μš©ν• λ•Œ μž…λ‹ˆλ‹€. Index Full Scan은 인덱슀 전체λ₯Ό ν™•μΈν•˜λŠ”λ° Min Maxλ₯Ό κ΅¬ν• λ•ŒλŠ” 인덱슀의 μ‹œμž‘ ν˜Ήμ€ 끝 ν•œλ²ˆ 건만 ν™•μΈν•˜κ³  탐색은 λλ‚΄λŠ” λ°©λ²•μœΌλ‘œ 1개의 블둝을 읽어 κ²°κ³Όλ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

 

νŠΉμ§•

  • 인덱슀의 λͺ¨λ“  블둝을 μ½λŠ”λ‹€.
  • μ •λ ¬ μž‘μ—…μ„ μƒλž΅ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λœλ‹€.
  • Not Null μ‘°κ±΄μœΌλ‘œλ„ 인덱슀 탐색이 κ°€λŠ₯ν•˜λ‹€.
  • Single Block Read

Full Table Scan과 Index Full Scan의 차이점?

κ°€μž₯ 큰 차이점은  Multi-Block Readκ°€ κ°€λŠ₯ μ—¬λΆ€ μž…λ‹ˆλ‹€. Full Table Scan은 Multi-Block Readκ°€ κ°€λŠ₯ν•˜μ§€λ§Œ Index Full Scan은 리프블둝을 일일히 λ°©λ¬Έν•˜κΈ° λ•Œλ¬Έμ— Single Block Read밖에 ν•  수 μ—†μŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ λ•Œλ‘œλŠ” Full Table Scan의 μ„±λŠ₯이 더 쒋을 λ•Œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

 

 

4. Index Fast Full Scan

Index Fast Full Scan은 말 κ·ΈλŒ€λ‘œ Index Full Scan보닀 λΉ λ₯΄λ‹€. μ „λΆ€λ₯Ό νƒμƒ‰ν•˜λ©΄μ„œ 더 λΉ λ₯΄κ²Œ κ²°κ³Όλ₯Ό 얻을 수 μžˆλŠ” μ΄μœ λŠ” Multi-Block Readκ°€ κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ 이둜 인해 μ •λ ¬λœ μƒνƒœλ‘œ 데이터λ₯Ό 받을 수 μ—†λ‹€λŠ” μ œν•œμ΄ μžˆμŠ΅λ‹ˆλ‹€. Index Full Scan은 λ°μ΄ν„°μ˜ 논리적인 μˆœμ„œλ‘œ κ²°κ³Όλ₯Ό μ–»μ§€λ§Œ Index Fast Full Scan은 λ°μ΄ν„°μ˜ 물리적 μ €μž₯ ꡬ쑰의 μˆœμ„œλ‘œ λ°›μ•„μ˜€κ³  κ·Έλž˜μ„œ Multi-Block Readκ°€ κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

μ˜ˆμ‹œ

JAMONG@orcl> select count(employee_id) from employees;
JAMONG@orcl> @xplan

Employees ν…Œμ΄λΈ”μ—μ„œ count둜 전체 κ²°κ³Όλ₯Ό λ°›μ•„μ™”μ„λ•Œ Index Full Scan을 μ‚¬μš©ν•˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. 그럼 λŒ€μš©λŸ‰μš© ν…Œμ΄λΈ”μ„ ν•˜λ‚˜ μƒμ„±ν•΄μ„œ λ˜‘κ°™μ€ 질의λ₯Ό ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

JAMONG@orcl> create table test as select * from employees;

JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;
JAMONG@orcl> insert into test select * from test;

JAMONG@orcl> create index test_emp_id_idx on test(employee_id);

JAMONG@orcl> select count(employee_id) from test;
JAMONG@orcl> @xplan

기쑴의 107κ°œμ˜€λ˜ employees ν…Œμ΄λΈ”μ„ λŒ€λž΅ 90만건의 데이터λ₯Ό 갖도둝 ν…Œμ΄λΈ”μ„ μƒμ„±ν–ˆμŠ΅λ‹ˆλ‹€. 이후 λ˜‘κ°™μ΄ employee_id에 인덱슀λ₯Ό 생성해주고 같은 쿼리λ₯Ό 질의 ν–ˆμŠ΅λŠ”λ° Index Fast Full Scan을 μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” 데이터가 λŠ˜μ–΄λ‚˜λ©΄μ„œ Index Fast Full Scan이 λΉ„μš©μ΄ 더 적게 λ“œλŠ” κ²ƒμœΌλ‘œ μ˜΅ν‹°λ§ˆμ΄μ €κ°€ νŒλ‹¨ν–ˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. 

 

Index Fast Full Scan은 주둜 힌트λ₯Ό μ‚¬μš©ν•΄μ„œ Multi Block Readκ°€ κ°€λŠ₯ν•˜λ„λ‘ μΏΌλ¦¬νŠœλ‹μ„ ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. Index Full Scan을 μ‚¬μš©ν•˜λŠ”λ° Disk I/Oκ°€ 많이 λ°œμƒν• λ•Œ μ‚¬μš©ν•˜λ©΄ νš¨κ³Όμ μž…λ‹ˆλ‹€. Index Fast Full Scan을 μ‚¬μš©ν•˜λ©΄ Disk I/OλŠ” λΉ„μŠ·ν•  수 μžˆμ–΄λ„ ν•œλ²ˆμ΄ μ½μ–΄λ“€μ΄λŠ” 블둝이 db_file_multiblock_read_count νŒŒλΌλ―Έν„° 만큼 이기 λ•Œλ¬Έμ— 순차적으둜 데이터λ₯Ό μ½μ–΄μ˜€κΈ° μœ„ν•΄ λ°œμƒν–ˆλ˜ λŒ€κΈ° 이벀트λ₯Ό 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.

 

νŠΉμ§•

  • Index Full Scan보닀 빠름
  • 물리적 μˆœμ„œλŒ€λ‘œ 탐색
  • Multi Block Read κ°€λŠ₯
  • 병렬 처리 κ°€λŠ₯

 

5. Index Skip Scan

Index Skip Scan은 Multi Column Indexμ—μ„œ ν›„ν–‰ μΉΌλŸΌμ„ μ‘°κ±΄μ ˆμ— μ‚¬μš©ν• λ•Œ ν™œμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ„±λ³„μ²˜λŸΌ 선두 칼럼의 고유 κ°’μ˜ κ°œμˆ˜κ°€ 적고 ν›„ν–‰ 칼럼의 고유 값이 λ§Žμ„ λ•Œ νš¨κ³Όμ μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ λΆ€μ„œκ°€ 10,20,30,40 인 νšŒμ‚¬κ°€ μžˆλŠ”λ° 직원이 1000λͺ…μž…λ‹ˆλ‹€. 각각 500,100,200,200 λͺ…μ˜ 직원이 μžˆμŠ΅λ‹ˆλ‹€. μš°λ¦¬κ°€ μ•Œκ³  싢은 λ‚΄μš©μ€ κΈ‰μ—¬κ°€ 5000 ~ 7000 사이인 μ§μ›μž…λ‹ˆλ‹€. μƒμ„±λœ μΈλ±λŠ” (λΆ€μ„œλ²ˆν˜Έ,κΈ‰μ—¬)둜 κ²°ν•©λœ μΈλ±μŠ€κ°€ μžˆμŠ΅λ‹ˆλ‹€. λ§Œμ•½ Index Skip Scan을 μ‚¬μš©ν•˜λ©΄ 10번 λΆ€μ„œμ—μ„œ 5000 ~ 7000인 직원을 μ°Ύκ³  κ·Έ 이후 10번 λΆ€μ„œμ˜ λ°μ΄ν„°λŠ” 확인할 ν•„μš”κ°€ μ—†κΈ° λ•Œλ¬Έμ— 20번 λΆ€μ„œλ‘œ λ„˜μ–΄κ°€μ„œ λ˜‘κ°™μ΄ λ°˜λ³΅ν•©λ‹ˆλ‹€. μ΄λŸ°μ‹μœΌλ‘œ ν•„μš”μ—†λŠ” 뢀뢄에 λŒ€ν•΄μ„œ κ±΄λ„ˆλ›΄λ‹€λ©΄ Full Table Scan보닀 μ„±λŠ₯이 쒋을 수 μžˆμŠ΅λ‹ˆλ‹€.

 

μ˜ˆμ‹œ

JAMONG@orcl> create index employees_dept_sal_idx on employees(department_id,salary);
JAMONG@orcl> 
select /*+index_ss(employees employees_dept_sal_idx)*/ * 
from employees 
where salary between 5000 and 7000;

λ§ˆλ•…ν•œ μ˜ˆμ‹œ 쿼리λ₯Ό μ°ΎκΈ° νž˜λ“€μ–΄ 힌트λ₯Ό μ‚¬μš©ν•΄μ„œ κ²°κ³Όλ₯Ό 좜λ ₯ν•΄λ΄€μŠ΅λ‹ˆλ‹€.

 

νŠΉμ§•

  • κ²°ν•© 인덱슀의 μ„ ν–‰ 칼럼이 쑰건식에 없어도 μ‚¬μš© κ°€λŠ₯
  • Single Block Read
  • μ„ λ‘μ»¬λŸΌ Distinct Value 적고 ν›„ν–‰ 컬럼 Distinct Value λ§Žμ„ λ•Œ 효과적

 

λŒ“κΈ€