[SQL BOOSTER] 6-1. INDEX์ ๊ธฐ๋ณธ ๊ฐ๋
by Hi.Claire๐ SQL BOOSTER (์ ์ผํ, DBian)
CH6. INDEX
6-1. INDEX์ ๊ฐ๋ณธ ๊ฐ๋
6-1-1. ์ธ๋ฑ์ค(INDEX)๋?
DB์ ์ธ๋ฑ์ค(INDEX)๋ ์ฑ ์ ์์ธ(INDEX)์ฒ๋ผ ํ ์ด๋ธ ๋ด์ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ์ ์๊ฒ ์ผ๋ถ ๋ฐ์ดํฐ๋ฅผ ๋ชจ์์ ๊ตฌ์ฑํ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ด๋ค.
์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ๋ฉด ํ ์ด๋ธ ๋ด์ ๋ฐ์ดํฐ๋ฅผ ๋น ๋ฅด๊ฒ ์ฐพ์๋ผ ์ ์๋ค.
์์1. ํ ์คํธ๋ฅผ ์ํ T_ORD_BIG ํ ์ด๋ธ ๋ง๋ค๊ธฐ
CREATE TABLE T_ORD_BIG AS
SELECT T1.*, T2.RNO, TO_CHAR(T1.ORD_DT, 'yyyymmdd') ORD_YMD
FROM T_ORD T1
, (SELECT ROWNUM RNO
FROM DUAL
CONNECT BY ROWNUM <= 10000) T2;
์์2. T_ORD_BIG ํ
์ด๋ธ์ ํต๊ณ ์์ฑํ๊ธฐ(์๋ฌ)
EXEC DBMS_STATS.GATHER_TABLE_STATS('test_user', 'T_ORD_BIG');
์์ SQL์ ์คํํ์ฌ T_ORD_BIG ํ ์ด๋ธ์ ํต๊ณ์ ๋ณด๋ฅผ ์์ฑํ๋ ค๋๋ฐ ๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
ORA-00900 ์ค๋ฅ์ ์์ธ์ ์ฐพ๊ธฐ ์ํด ๊ตฌ๊ธ๋งํด๋ณด์๋ค.
EXEC ๋ช ๋ น์ด๋ PL/SQL ๋ช ๋ น์ด๊ฐ ์๋ SQL*Plus ๋ช ๋ น์ด์ด๊ธฐ ๋๋ฌธ์ EXEC ๋์ BEGIN ... END; ๋ฅผ ์ฌ์ฉํด๋ณด๋ผ๋ ๋๊ธ์ ๋ณด๊ฒ๋์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์๋ค.
How to resolve issue of stored proc not executing dbms_stats.gather_table_stats() when executing as it string via EXECUTE IMMEDI
In my stored procedure, I am using "EXECUTE IMMEDIATE" to execute statement that is in string format but this is not generating the result. I have added proc below: CREATE OR REPLACE PROC...
stackoverflow.com
์์2. T_ORD_BIG ํ ์ด๋ธ์ ํต๊ณ ์์ฑํ๊ธฐ
BEGIN
DBMS_STATS.GATHER_TABLE_STATS('test_user', 'T_ORD_BIG');
END;
์์3. ์ธ๋ฑ์ค๊ฐ ์๋ T_ORD_BIG ํ ์ด๋ธ ์กฐํ - ORD_SEQ๊ฐ 343์ธ ๋ฐ์ดํฐ ์นด์ดํธํ๊ธฐ
SELECT /*+ GATHER_PLAN_STATISTICS */
COUNT(*)
FROM t_ord_big big
WHERE big.ord_seq = 343;
์คํ๊ณํ ํ์ธ
SELECT T1.sql_id, T1.child_number, T1.sql_text
FROM v$sql T1
WHERE T1.sql_text LIKE '%GATHER_PLAN_STATISTICS%'
ORDER BY T1.last_active_time DESC;
SELECT *
FROM TABLE (dbms_xplan.DISPLAY_CURSOR('0bnmdbygb56pk',0,'ALLSTATS LAST'));
์ค์ ์คํ๊ณํ์ ํ์ธํด๋ณด๋ ์๊ฐ์ 9์ด๊ฐ ๊ฑธ๋ ธ๊ณ , ์ ์ฒด Buffers(๋ ผ๋ฆฌ์ IO)๋ 258K๊ฐ ๋์๋ค.
์คํ ์์๋ ํ ์ด๋ธ ์ ์ฒด๋ฅผ ์ฝ์ด์ ORD_SEQ๊ฐ 343์ธ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์๋ด์ ์นด์ดํธ ์ฒ๋ฆฌ๋ฅผ ํ ๊ฒ์ผ๋ก ๋์จ๋ค.
์ด์ WHERE ์กฐ๊ฑด์ ์ ์ฌ์ฉ๋ ORD_SEQ ์ปฌ๋ผ์ ์ธ๋ฑ์ค๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ๋ค.
์์4. ORD_SEQ ์ปฌ๋ผ์ ์ธ๋ฑ์ค ๊ตฌ์ฑํ๊ธฐ
CREATE INDEX X_T_ORD_BIG_TEST ON T_ORD_BIG(ORD_SEQ);
์์5. ์ธ๋ฑ์ค๊ฐ ์กด์ฌํ๋ T_ORD_BIG ํ ์ด๋ธ ์กฐํ - ORD_SEQ๊ฐ 343์ธ ๋ฐ์ดํฐ ์นด์ดํธํ๊ธฐ
SELECT /*+ GATHER_PLAN_STATISTICS */
COUNT(*)
FROM t_ord_big big
WHERE big.ord_seq = 343;
์คํ๊ณํ
์ธ๋ฑ์ค๋ฅผ ์์ฑํ ํ ๋์ผํ SQL์ ์คํํ์ฌ ์ค์ ์คํ๊ณํ์ ํ์ธํด๋ณด๋ฉด ์ํ์๊ฐ์ด 9์ด์์ 0.05์ด๋ก ์ค์๊ณ , ์ ์ฒด Buffers๋ 258K์์ 24๋ก ์ข์์ง ๊ฒ์ ํ์ธํ ์ ์๋ค.
์คํ ์์๋ฅผ ์ดํด๋ณด๋ฉด ์ธ๋ฑ์ค(X_T_ORD_BIG_TEST)๋ฅผ ์ฌ์ฉํด์ ORD_SEQ๊ฐ 343์ธ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ํ ์นด์ดํธ ์ฒ๋ฆฌ๋ฅผ ํ ๊ฒ์ ์ ์ ์๋ค.
์ด์ฒ๋ผ ์ธ๋ฑ์ค๋ฅผ ๋ง๋๋ ๊ฒ๋ง์ผ๋ก ์ฑ๋ฅ์ด ํฅ์๋ ์ ์๋ค.
6-1-2. ์ธ๋ฑ์ค์ ์ข ๋ฅ
์ธ๋ฑ์ค๋ ๊ธฐ์ค์ ๋ฐ๋ผ ๋ค์ํ๊ฒ ๊ตฌ๋ถํ ์ ์๋ค.
(1) ์ธ๋ฑ์ค๋ฅผ ๊ตฌ์ฑํ๋ ์ปฌ๋ผ ์์ ๋ฐ๋ผ ๊ตฌ๋ถ
๋จ์ผ ์ธ๋ฑ์ค(Single column index) : ์ธ๋ฑ์ค์ ํ๋์ ์ปฌ๋ผ๋ง ์ฌ์ฉ
๋ณตํฉ ์ธ๋ฑ์ค(Composite index) : ์ธ๋ฑ์ค์ ๋ ๊ฐ ์ด์์ ์ปฌ๋ผ์ ์ฌ์ฉ
๋จ์ผ ์ธ๋ฑ์ค๋ PK ์์ฑ์ด ๋จ์ผ ์ปฌ๋ผ์ผ ๋ ์ฃผ๋ก ์ฌ์ฉํ๋ค.
์ ๋ง๋ค์ด์ง ํ๋์ ๋ณตํฉ ์ธ๋ฑ์ค๋ ์ฌ๋ฌ๊ฐ์ ์ธ๋ฑ์ค๋ฅผ ๋์ ํ ์ ์์ผ๋ฉฐ, ์ฌ๋ฌ SQL์ ์ฑ๋ฅ์ ์ปค๋ฒํ ์๋ ์๋ค.
๊ฐ๋ฅํ๋ฉด ํ๋์ ๋ณตํฉ ์ธ๋ฑ์ค๋ก ์ฌ๋ฌ SQL์ ์ปค๋ฒํ๋ ๊ฒ์ด ์ข๋ค.
SQL๋ณ๋ก ํ์ํ ์ธ๋ฑ์ค๋ฅผ ๋ชจ๋ ๋ง๋ค๋ค๋ณด๋ฉด ์ธ๋ฑ์ค๊ฐ ๋๋ฌด ๋ง์์ง๊ธฐ ๋๋ฌธ์ด๋ค.
(2) ์ธ๋ฑ์ค๋ฅผ ๊ตฌ์ฑํ๋ ์ปฌ๋ผ ๊ฐ์ ์ค๋ณต ํ์ฉ ์ฌ๋ถ์ ๋ฐ๋ผ ๊ตฌ๋ถ
์ ๋ํฌ ์ธ๋ฑ์ค(Unique index) : ์ธ๋ฑ์ค ๊ตฌ์ฑ ์ปฌ๋ผ ๊ฐ์ ์ค๋ณต์ ํ์ฉํ์ง ์๋๋ค.
๋น์ ๋ํฌ ์ธ๋ฑ์ค(Non-unique index) : ์ธ๋ฑ์ค ๊ตฌ์ฑ ์ปฌ๋ผ ๊ฐ์ ์ค๋ณต์ ํ์ฉํ๋ค.
PK ์ ์ฝ์กฐ๊ฑด์๋ ๋ฌด์กฐ๊ฑด ์ ๋ํฌ ์ธ๋ฑ์ค๊ฐ ๊ตฌ์ฑ๋๋ค. (PK๋ ์๋์ผ๋ก ์ธ๋ฑ์ค๊ฐ ๋ง๋ค์ด์ง๋ค.)
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ ์์ ๋ถํฐ ์ ๋ฌด์ ์ผ๋ก ์ ๋ํฌํ ์์ฑ๋ค์ ํ์ ํด์ ์ ๋ํฌ ์ธ๋ฑ์ค๋ฅผ ๋ง๋ค์ด์ฃผ๋ ๊ฒ์ด ์ข๋ค.
(3) ์ธ๋ฑ์ค์ ๋ฌผ๋ฆฌ์ ๊ตฌ์กฐ์ ๋ฐ๋ผ ๊ตฌ๋ถ
B* ํธ๋ฆฌ ์ธ๋ฑ์ค(B*Tree index) : ํธ๋ฆฌ ํํ์ ์๋ฃ ๊ตฌ์กฐ ์ฌ์ฉ, OLTP ์์คํ ์ ๋๋ถ๋ถ B* ํธ๋ฆฌ ๊ตฌ์กฐ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ค.
๋นํธ๋งต ์ธ๋ฑ์ค(Bitmap index) : ๊ฐ์ ์ข ๋ฅ๊ฐ ๋ง์ง ์์ ์ปฌ๋ผ์ ์ฌ์ฉํ๋ค.
(4) ํํฐ์ ๋ ์ธ๋ฑ์ค
๊ธ๋ก๋ฒ ์ธ๋ฑ์ค
๋ก์ปฌ ์ธ๋ฑ์ค
์์ ๋ถ๋ฅ๋ฅผ ํผํฉํด์ ์ธ๋ฑ์ค๋ฅผ ์์ฑํ ์๋ ์๋ค.
6-1-3. B*ํธ๋ฆฌ ๊ตฌ์กฐ์ ํ์ ๋ฐฉ๋ฒ
์ธ๋ฑ์ค๋ฅผ ์์ฑํ ๋ ๋ณ๋ค๋ฅธ ์ต์ ์ ์ ์ํ์ง ์์ผ๋ฉด B*ํธ๋ฆฌ ๊ตฌ์กฐ์ ์ธ๋ฑ์ค๊ฐ ๋ง๋ค์ด์ง๋ค.
B*ํธ๋ฆฌ ๊ตฌ์กฐ
- B(balanced) : ๊ท ํ์ด ์กํ ์๋ค, ๋ฆฌํ ๋ ธ๋๋ค์ด ๊ฐ์ ์์ค(๊น์ด)์ ์๋ฆฌํด ์๋ค.
- *(star) : ๊ทผ์ ํ ๋ฆฌํ ๋ ธ๋๊ฐ ์ฐ๊ฒฐ(link)๋ ๊ตฌ์กฐ
์ ๋ฆฌํด๋ณด๋ฉด, B* ํธ๋ฆฌ๋ ๊ท ํ์ด ์กํ ์๊ณ ๊ทผ์ ํ ๋ฆฌํ ๋ ธ๋๊ฐ ์ฐ๊ฒฐ๋ ๊ตฌ์กฐ๋ค.
B* ํธ๋ฆฌ๋ ๋ฃจํธ(root, ๋ฟ๋ฆฌ), ๋ธ๋์น(branch, ๊ฐ์ง), ๋ฆฌํ(leaf, ์์ฌ๊ท) ์ธ ๊ฐ์ง ์ ํ์ ๋ธ๋ก์ผ๋ก ๊ตฌ์ฑ๋์ด ์๋ค.
๋๋ฌด์์ ๋ฟ๋ฆฌ๋ ํ๋์ง๋ง, ๊ฐ์ง๋ ๋งค์ฐ ๋ง๊ณ , ์์ฌ๊ท๋ ๋ ๋ง๋ฏ์ด B* ํธ๋ฆฌ๋ ์ ์ฒด์ ์ผ๋ก ์ผ๊ฐํ ๋ชจ์์ด ๋๋ค.
์ธ๋ฑ์ค๋ฅผ ๊ตฌ์ฑํ๋ ๋ธ๋ก์ ์ธ๋ฑ์ค ๋ธ๋ก์ด๋ผ๊ณ ํ๋ฉฐ, ์ธ๋ฑ์ค ๋ธ๋ก์ ์๋ก ์ฐ๊ฒฐ๋์ด ์๋ค.
๋ฃจํธ๋ ์์ ์ ํ์ ๋ธ๋์น์, ๊ฐ ๋ธ๋์น๋ ๊ฐ๊ฐ ์์ ์ ํ์ ๋ธ๋์น๋ ๋ฆฌํ ๋ธ๋ก๊ณผ ์ฐ๊ฒฐ๋์ด ์๋ค.
๋ฆฌํ ๋ธ๋ก ๋ฐ์ผ๋ก๋ ๋ค๋ฅธ ์ธ๋ฑ์ค ๋ธ๋ก์ ์๋ค.
์ธ๋ฑ์ค ๋ธ๋ก์ ๊ตฌ์ฑ
๋ฃจํธ ๋ธ๋ก
- ์ต์์์ ๋จ ํ๋๋ง ์กด์ฌ
- ํ์ ๋ธ๋์น ๋ธ๋ก์ ์ธ๋ฑ์ค ํค ๊ฐ๊ณผ ์ฃผ์๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
๋ธ๋์น ๋ธ๋ก
- ๋ฃจํธ์ ๋ฆฌํ์ ์ค๊ฐ์ ์์น, ๋ธ๋์น๋ ์ฌ๋ฌ ์ธต์ด ์์ ์ ์๋ค.
- ํ์ ๋ธ๋์น ๋๋ ํ์ ๋ฆฌํ์ ์ธ๋ฑ์ค ํค ๊ฐ๊ณผ ์ฃผ์๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
๋ฆฌํ ๋ธ๋ก
- ์ตํ์์๋ง ์์น
- ์ธ๋ฑ์ค ํค ๊ฐ๊ณผ ๋ฐ์ดํฐ์ ๋ก์ฐ ์์น(ROWID)๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
- ๋ฆฌํ ๋ธ๋ก์ ์ธ๋ฑ์ค ํค ๊ฐ ์์ผ๋ก ์ ๋ ฌ๋์ด ์๋ค.
B* ํธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ฐพ์๊ฐ๋ ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
ORD_YMD๋ก ๊ตฌ์ฑ๋ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด 'ORD_YMD = 20170104'์ธ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์๋ด๋ณด์.
(1) ๋ฃจํธ ๋ธ๋ก
์ ๊ทธ๋ฆผ์์ ๋ฃจํธ ๋ธ๋ก(B99)๋ฅผ ๋ณด๋ฉด ์ธ ๊ฐ์ ๋ธ๋์น ๋ธ๋ก(B05, B06, B01)์ ์ฐพ์๊ฐ ์ ์๋ค.
'20170104'๋ ๋น ๊ฐ๋ณด๋ค ํฌ๊ณ '20170601'๋ณด๋ค ์๋ค.
๊ทธ๋ฌ๋ฏ๋ก ๋ธ๋์น ๋ธ๋ก ์ค์์ B05 ๋ธ๋ก์ผ๋ก ์ด๋ํด์ผ ํ๋ค.
(2) ๋ธ๋์น ๋ธ๋ก
๊ทธ๋ฆผ์์ B05 ๋ธ๋ก์ ์ธ ๊ฐ์ ๋ฆฌํ ๋ธ๋ก(B02, B10, B21)์ ๊ฐ์ง๊ณ ์๋ค.
'20170104'๋ '20170102'๋ณด๋ค ํฌ๊ณ '20170104'๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค.
๊ทธ๋ฌ๋ฏ๋ก B10์ผ๋ก ์ด๋ํด์ผ ํ๋ค.
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ B10 ๋ท๋ถ๋ถ์๋ '20170104'๊ฐ ์ผ๋ถ ์์ ์ ์๊ธฐ ๋๋ฌธ์ B21์ด ์๋ B10์ผ๋ก ์ด๋ํด์ผ ํ๋ค๋ ์ ์ด๋ค.
(3) ๋ฆฌํ ๋ธ๋ก
์ธ๋ฑ์ค๋ฅผ ๊ฒ์ํด์ ๋ฆฌํ ๋ธ๋ก์ ๋๋ฌํ๋ฉด ์ด์ ๋ ๋ฆฌํ ๋ธ๋ก์ ์ฐจ๋ก๋๋ก ์ค์บํด์ผ ํ๋ค.
์ค์บ ์์ ์ ์ฐพ์ผ๋ ค๋ ๊ฐ๋ณด๋ค ํฐ ๊ฐ์ ๋ฐ๊ฒฌํ๊ธฐ ์ ๊น์ง ์ํํ๋ค.
์ฌ๊ธฐ์๋ B10 ๋ธ๋ก์ ์ฒซ ๋ฒ์งธ ๋ฐ์ดํฐ์์ ์์ํด B21 ๋ธ๋ก์ '20170105'๋ฅผ ๋ง๋ ๋๊น์ง ์ค์บ์ด ์งํ๋๋ค.
์ด๋ ๋ฆฌํ ๋ธ๋ก์ ์ค์บํ๋ฉด์ ROWID๋ฅผ ์ฐธ๊ณ ํด ์ค์ ํ ์ด๋ธ์ ์ ๊ทผํ๋ ์์ ์ ์ํํ๋ค.
ROWID๋ ๋ฐ์ดํฐ๊ฐ ์ค์ ์ ์ฅ๋ ์ฃผ์ ๊ฐ์ด๋ค.
ROWID๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ฐพ์๋ด๋ ๊ณผ์ ์ ์คํ๊ณํ์ 'TABLE ACCESS BY INDEX ROWID'๋ผ๋ ์คํผ๋ ์ด์ ์ผ๋ก ๋ํ๋๋ค.
6-1-4. ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ
์ค๋ผํด์์ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ
- ํ ์ด๋ธ ์ ์ฒด ์ฝ๊ธฐ(TABLE ACCESS FULL)
- ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ ์ฐพ๊ธฐ(INDEX RANGE SCAN & TABLE ACCESS BY INDEX ROWID)
- ROWID๋ฅผ ์ด์ฉํ ์ง์ ์ฐพ๊ธฐ(TABLE ACCESS BY INDEX ROWID)
6-1-5. ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ - ํ ์ด๋ธ ์ ์ฒด ์ฝ๊ธฐ
ํ ์ด๋ธ ์ ์ฒด ์ฝ๊ธฐ๋ ํ ์ด๋ธ์ ๋ฐ์ดํฐ ๋ธ๋ก์ ์ฐจ๋ก๋๋ก ๋ชจ๋ ์ฝ์ผ๋ฉด์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ์ด๋ค.
์คํ๊ณํ์ 'TABLE ACCESS FULL'๋ก ํํ๋๋ค.
ํ ์ด๋ธ ์ ์ฒด ์ฝ๊ธฐ๋ ์ฐพ๊ณ ์ ํ๋ ์กฐ๊ฑด์ ํ์ฉํ ์ธ๋ฑ์ค๊ฐ ์๊ฑฐ๋ ์ธ๋ฑ์ค๋ณด๋ค ํ ์ด๋ธ ์ ์ฒด๋ฅผ ์ฝ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ด๋ผ๊ณ ํ๋จํ ๋ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ค๋ผํด์์ ๋ฐ์ดํฐ๊ฐ ํ ์ด๋ธ์ ์ ์ฅ๋ ๋๋ ํน์ ์์๋ฅผ ๊ฐ์ง ์๋๋ค.
ํ ์ด๋ธ ๋ด์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ ์ด๋ค ๊ธฐ์ค์ผ๋ก๋ ์ ๋ ฌ๋์ด ์์ง ์๋ค.
๋ฐ๋ผ์ ์ค๋ผํด์ ์ฐพ์ผ๋ ค๋ ๋ฐ์ดํฐ๊ฐ ์ด๋์ ์๊ณ , ์ ํํ ๋ช ๊ฑด ์๋์ง ์์ง ๋ชปํ๋ค.
๋ชจ๋ ํ ์ด๋ธ ๋ธ๋ก์ ์ฝ์ด์ผ๋ง ์กฐ๊ฑด์ด ๋ง๋ ๋ฐ์ดํฐ๋ฅผ ๋น ์ง์์ด ์ฐพ์๋ผ ์ ์๋ค.
WHERE ์กฐ๊ฑด์ ์ ์ฌ์ฉ๋ ์ปฌ๋ผ์ ์ ์ ํ ์ธ๋ฑ์ค๊ฐ ์๋ค๋ฉด, ํ ์ด๋ธ ์ ์ฒด ์ฝ๊ธฐ(TABLE ACCESS FULL)๋ง์ด ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ์ ์๋ ์ ์ผํ ๋ฐฉ๋ฒ์ด๋ค.
์์1. TABLE ACCESS FULL์ ์ฌ์ฉํ๋ SQL - ๊ณ ๊ฐ๋ณ '20170316' ์ผ์์ ์ฃผ๋ฌธ ๊ฑด์ ์ฐพ๊ธฐ
SELECT /*+ GATHER_PLAN_STATISTICS */
T1.cus_id
, count(*) ORD_CNT
FROM t_ord_big T1
WHERE T1.ord_ymd = '20170316'
GROUP BY T1.cus_id
ORDER BY T1.cus_id;
์คํ๊ณํ
์ ์คํ๊ณํ 2๋ฒ ์คํผ๋ ์ด์ ์ ๋ณด๋ฉด TABLE ACCESS FULL์ด ์๋ ๊ฒ์ ์ ์ ์๋ค.
TABLE ACCESS FULL์ ํ ์ด๋ธ ๋ธ๋ก ์ ์ฒด๋ฅผ ์ฝ๋๋ค.
๊ทธ๋ฌ๋ฏ๋ก ํ ์ด๋ธ์ด ํด์๋ก ์ค๋ ๊ฑธ๋ฆฐ๋ค.
๋ง์ฝ์ ์ฒ๋ง ๊ฑด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ํ ์ด๋ธ์์ ์ฐพ๊ณ ์ ํ๋ ๋ฐ์ดํฐ๊ฐ ํ ๊ฑด์ด๋ผ๋ฉด TABLE ACCESS FULL์ ๋งค์ฐ ๋นํจ์จ์ ์ด๋ค.
์ด๋ฐ ๊ฒฝ์ฐ์๋ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ฐพ์๋ด๋ ๊ฒ์ด ํจ์จ์ ์ด๋ค.
ํ์ง๋ง ์ฒ๋ง ๊ฑด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ํ ์ด๋ธ์์ ์ฐพ์์ผ ํ๋ ๋ฐ์ดํฐ๊ฐ ๋ฐฑ๋ง ๊ฑด ์ ๋ ๋๋ค๋ฉด ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค TABLE ACCESS FULL์ด ๋ ํจ์จ์ ์ผ ์ ์๋ค.
์ด์ฒ๋ผ TABLE ACCESS FULL์ด ๋ฌด์กฐ๊ฑด ์ฑ๋ฅ์ด ๋์ ๊ฒ์ ์๋๋ค.
6-1-6. ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ - ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ ์ฐพ๊ธฐ
์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ ์ฐพ๊ธฐ๋ ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ํ์ํ ๋ฐ์ดํฐ๋ง ์ฐพ๋ ๋ฐฉ๋ฒ์ด๋ค.
'INDEX RANGE SCAN', 'INDEX SKIP SCAN', 'INDEX FULL SCAN' ๋ฑ ๋ค์ํ ๋ฐฉ์์ด ์์ง๋ง, ์ด ์ฑ ์์๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ธ 'INDEX RANGE SCAN'์ ๋ํด ์ค๋ช ํ๋ค.
์ด ๋ฐฉ๋ฒ์ ํ์์ ๋ฐ๋ผ 'TABLE ACCESS BY INDEX ROWID' ์์ ์ ๋๋ฐํ๋ค.
์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๊ณผ์ ์ ์ ์ฒด์ ์ผ๋ก ๊ทธ๋ ค๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
1. ๋ฃจํ์์ ๋ฆฌํ๋ก : ๊ฒ์ ์กฐ๊ฑด์ ํด๋นํ๋ ์ฒซ ๋ฒ์งธ ๋ฆฌํ ๋ธ๋ก์ ์ฐพ๋ ๊ณผ์
2. ๋ฆฌํ ๋ธ๋ก ์ค์บ : ์ฐพ์๋ธ ์ง์ ๋ถํฐ ๋ฆฌํ ๋ธ๋ก์ ์ฐจ๋ก๋๋ก ์ฝ์ด ๊ฐ๋ ๊ณผ์
3. ํ ์ด๋ธ ์ ๊ทผ : ๋ฆฌํ ๋ธ๋ก์ ์ค์บํ๋ฉด์ ํ์์ ๋ฐ๋ผ ํ ์ด๋ธ์ ์ ๊ทผํ๋ ๊ณผ์
์ ์ค๋ช ์์ 1๋ฒ๊ณผ 2๋ฒ์ ๋ฌถ์ด์ 'INDEX RANGE SCAN'์ด๋ผ๊ณ ํ๋ค.
'INDEX RANGE SCAN'์ ํ์์ ๋ฐ๋ผ 'TABLE ACCESS BY INDEX ROWID' ์์ ์ ๋๋ฐํ๋ค.
์ธ๋ฑ์ค๋ฅผ ์ด์ฉํด ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๊ณผ์ ์ ์์ธํ๊ฒ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
(1) ๋ฃจํธ์์ ๋ฆฌํ๋ก (๋ฆฌํ ๋ธ๋ก ์ฐพ๊ธฐ)
๋ฃจํธ ๋ธ๋ก์์ ์ฃผ์ด์ง ์กฐ๊ฑด์ด ์ ์ฅ๋ ๋ฆฌํ ๋ธ๋ก์ ์ฐพ์๊ฐ๋ ๊ณผ์ ์ด๋ค.
์ด ๊ณผ์ ์ ๋ถํ๊ฐ ์๋ค๊ณ ์๊ฐํด๋ ๋ ์ ๋๋ก ๋งค์ฐ ๋น ๋ฅด๊ฒ ์ด๋ฃจ์ด์ง๋ค.
(2) ๋ฆฌํ ๋ธ๋ก ์ค์บ(RANGE SCAN)
๋ฆฌํ ๋ธ๋ก์ ์ธ๋ฑ์ค์ ํค ์ปฌ๋ผ์ธ ORD_YMD ์ปฌ๋ผ ๊ฐ์ ์์ผ๋ก ์ ๋ ฌ๋์ด ์๋ค.
์๋ฅผ ๋ค์ด ORD_YMD๊ฐ '20170103'์ธ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ๊ณ ์๋ค.
'๋ฃจํธ์์ ๋ฆฌํ๋ก' ๊ณผ์ ์์ '20170103'์ด ์ต์ด๋ก ์ ์ฅ๋ 3๋ฒ ๋ฆฌํ ๋ธ๋ก์ ์ฐพ์๋๋ค๊ณ ๊ฐ์ ํ์.
3๋ฒ ๋ฆฌํ ๋ธ๋ก์ ์ฐพ์๋ธ ํ์๋ ๋ฆฌํ ๋ธ๋ก ๋ด์ ๋ฐ์ดํฐ๋ฅผ ์ฐจ๋ก๋๋ก ์ฝ์ด ๋๊ฐ๋ค. ์ฐจ๋ก๋๋ก ์ฝ์ด๋๊ฐ๋ ๊ณผ์ ์ ORD_YMD๊ฐ '20170103'๋ณด๋ค ํฐ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ ๋๊น์ง๋ค.
์ด ๊ณผ์ ์ด ๋ฆฌํ ๋ธ๋ก ์ค์บ์ด๋ค.
(3) ํ ์ด๋ธ ์ ๊ทผ(TABLE ACCESS BY INDEX ROWID)
'๋ฆฌํ ๋ธ๋ก ์ค์บ' ๊ณผ์ ์์๋ ํ์์ ๋ฐ๋ผ ํ ์ด๋ธ์ ์ ๊ทผํ๋ค.
์ธ๋ฑ์ค ๋ฆฌํ ๋ธ๋ก์ ROWID ๊ฐ์ ์ฐธ์กฐํด ํ ์ด๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์๊ฐ๋ ๊ณผ์ ์ด๋ค.
์ด ๊ณผ์ ์ ํ ์ด๋ธ์ ํ์ํ ๊ฐ์ด ์์ ๋๋ง ์ผ์ด๋๋ค. ๋ง์ฝ์ ORD_YMD ๊ฐ๋ง ์ฌ์ฉํด SQL์ ์ฒ๋ฆฌํ ์ ์๋ค๋ฉด ์ด ๊ณผ์ ์ ์๋ต๋๋ค.
์ด์ ์ค์ ์ธ๋ฑ์ค๋ฅผ ๋ง๋ค์ด ํ ์คํธํด๋ณด์.
์์1. INDEX RANGE SCAN์ ์ฌ์ฉํ๋ SQL
ORD_YMD ์ปฌ๋ผ์ ์ธ๋ฑ์ค ๊ตฌ์ฑํ๊ธฐ
CREATE INDEX X_T_ORD_BIG_1 ON t_ord_big(ord_ymd);
๊ณ ๊ฐ๋ณ ord_ymd๊ฐ '20170316'์ธ ์ฃผ๋ฌธ ๊ฑด์ ์นด์ดํธํ๊ธฐ
SELECT /*+ GATHER_PLAN_STATISTICS INDEX(T1 X_T_ORD_BIG_1) */
T1.cus_id
, count(*) ord_cnt
FROM t_ord_big T1
WHERE T1.ord_ymd = '20170316'
GROUP BY T1.cus_id
ORDER BY T1.cus_id;
INDEX(T1 X_T_ORD_BIG_1) ํํธ๋ฅผ ์ฌ์ฉํด ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋๋ก ๊ฐ์ ํ๊ณ ์๋ค.
ํํธ๋ SQL ์ฒ๋ฆฌ ๋ฐฉ๋ฒ(์คํ๊ณํ)๋ง ๋ณ๊ฒฝํ ๋ฟ ์คํ ๊ฒฐ๊ณผ์๋ ์ ๋ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
์คํ๊ณํ
WHERE ์กฐ๊ฑด์ ๋ง๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๊ธฐ ์ํด 'INDEX RANGE SCAN'์ ์ฌ์ฉํ๊ณ , ์ธ๋ฑ์ค์ ์๋ 'cus_id' ๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ ์ํด 'TABLE ACCESS BY INDEX ROWID' ์์ ๊น์ง ์ํํ๋ค.
(์ฐธ๊ณ ) X_T_ORD_BIG_1 ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ SQL์ ์ฒ์ ์คํ์๋ 9.4์ด๊ฐ ๊ฑธ๋ฆฌ์ง๋ง ๋ ๋ฒ์งธ ์คํ๋ถํฐ๋ 1.57์ด ์ ๋๋ก ๋งค์ฐ ๋น ๋ฅด๊ฒ ์คํ๋๋ค. ๋ ๋ฒ์งธ ์คํ๋ถํฐ๋ ๋ฌผ๋ฆฌ์ IO์์ด ๋ ผ๋ฆฌ์ IO๋ก๋ง SQL์ด ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์ด๋ค.
6-1-7. INDEX RANGE SCAN VS. TABLE ACCESS FULL
๋๋ค ์์ธ์ค(RANDOM ACCESS)
IO ์์ ํ ๋ฒ์ ํ๋์ ๋ธ๋ก์ ๊ฐ์ ธ์ค๋ ์ ๊ทผ ๋ฐฉ๋ฒ์ ๋ปํ๋ค.
์ธ๋ฑ์ค์ ๋ฆฌํ ๋ธ๋ก์์ ROWID๋ฅผ ์ด์ฉํด ํ ์ด๋ธ์ ์ ๊ทผํ ๋ ๋๋ค ์์ธ์ค๊ฐ ๋ฐ์ํ๋ค.
์คํ๊ณํ์๋ 'TABLE ACCESS BY INDEX ROWID'๋ก ํ์๋๋ค.
๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ๋, '์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ ์ฐพ๊ธฐ'์ 'ํ ์ด๋ธ ์ ์ฒด ์ฝ๊ธฐ'์ ์ฑ๋ฅ์ ๋น๊ตํด ๋ณด์.
์์1. ORD_YMD ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ์ ๋ ์ฑ๋ฅ์ด ๋ ์ข์ SQL
SELECT /*+ GATHER_PLAN_STATISTICS */
T1.cus_id
, count(*) ord_cnt
FROM t_ord_big T1
WHERE T1.ord_ymd = '20170316'
GROUP BY T1.cus_id
ORDER BY T1.cus_id;
WHERE ์กฐ๊ฑด์ ์ ๋ณด๋ฉด ord_ymd๊ฐ '20170316'์ธ ์ฃผ๋ฌธ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๊ณ ์๋ค.
t_ord_big ํ ์ด๋ธ์๋ ์ด 3์ฒ๋ง ๊ฑด ์ ๋์ ๋ฐ์ดํฐ๊ฐ ์๋ค. ๊ทธ ์ค์ ord_ymd๊ฐ '20170316'์ธ ๋ฐ์ดํฐ๋ 5๋ง ๊ฑด์ด๋ค.
3์ฒ๋ง ๊ฑด์์ 5๋ง ๊ฑด ์ ๋๋ฅผ ์ฐพ๋ ๊ฒฝ์ฐ๋ผ๋ฉด 'INDEX RANGE SCAN'์ด ํจ์จ์ ์ด๋ผ๊ณ ํ๋จํ ์ ์๋ค.
(์ ํํ๊ฒ๋ ๋ฐ์ดํฐ ๊ฑด์๊ฐ ์๋ ๋ธ๋ก ์๋ก ํ๋จํด์ผ ํ๋ค.)
์์2. ORD_YMD ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ์ ๋ ์ฑ๋ฅ์ด ์์ข์ SQL
SELECT /*+ GATHER_PLAN_STATISTICS INDEX(T1 X_T_ORD_BIG_1) */
T1.ord_st
, sum(ord_amt) sum_amt
FROM t_ord_big T1
WHERE T1.ord_ymd >= '20170401'
AND T1.ord_ymd < '20170701'
GROUP BY T1.ord_st;
t_ord_big ํ ์ด๋ธ์์ 3๊ฐ์ ๊ฐ์ ์ฃผ๋ฌธ์ ์กฐํํ๋ค.
์ฝ 7,650,000 ๊ฑด์ ๋ฌํ๋ ๋๋ ๋ฐ์ดํฐ๋ค.
์คํ๊ณํ
X_T_ORD_BIG_1 ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋๋ก ํํธ๋ฅผ ์ฃผ์๋ค.
์ด SQL์ 4๋ถ์ด ๊ฑธ๋ฆฐ๋ค. ์ ์ฒด Buffers๋ฅผ ์ดํด๋ณด๋ฉด 1011K๋ค. ๋ง์ ๋ ผ๋ฆฌ์ IO๊ฐ ๋ฐ์ํ๋ค.
์คํ๊ณํ์ ๋ณด๋ฉด 'TABLE ACCESS BY INDEX ROWID'๊ฐ 7,650K๋ฒ ์คํ๋์๋ค.
'TABLE ACCESS BY INDEX ROWID'๋ ๋ฐ๋ก ์ ๋จ๊ณ์ธ 'INDEX RANGE SCAN'์ A-rows๋งํผ ์คํ๋๋ค.
์ฆ, ๋งค์ฐ ๋ง์ ๋๋ค ์์ธ์ค๊ฐ ๋ฐ์ํ์์ ์ ์ ์๋ค.
์์3. ํ ์ด๋ธ ์ ์ฒด ์ฝ๊ธฐ ๋ฐฉ์์ ์ฌ์ฉํ์ ๋ ์ฑ๋ฅ์ด ๋ ์ข์ SQL
SELECT /*+ GATHER_PLAN_STATISTICS FULL(T1) */
T1.ord_st
, sum(ord_amt) sum_amt
FROM t_ord_big T1
WHERE T1.ord_ymd >= '20170401'
AND T1.ord_ymd < '20170701'
GROUP BY T1.ord_st;
์คํ๊ณํ
'FULL(T1)' ํํธ๋ฅผ ์ฌ์ฉํ์ ์ธ๋ฑ์ค๋ก ์ฒ๋ฆฌํ ๋๋ณด๋ค ์๋๊ฐ ๋นจ๋ผ์ก๋ค.
์ด ์คํ ์๊ฐ์ด 4๋ถ์์ 1๋ถ 21์ด๋ก ๋จ์ถ๋์๋ค. Buffers ์์น๋ 1011K์์ 258K๋ก ์ข์์ก๋ค.
์ฆ, ์ฐพ๊ณ ์ ํ๋ ๋ฐ์ดํฐ๊ฐ ํน์ ์์ค ์ด์์ผ๋ก ๋ง์ผ๋ฉด ์ธ๋ฑ์ค๋ฅผ ์ด์ฉํ '๋๋ค ์์ธ์ค'๋ณด๋ค 'FULL SCAN' ๋ฐฉ์์ด ๋ ํจ์จ์ ์ด๋ค.
์ฐพ์์ผ ํ๋ ๋ฐ์ดํฐ๊ฐ ์ ๋์ ์ผ๋ก ๋ง๋ค๋ฉด 'FULL SCAN'์ด ๋ ์ข์ ์ฑ๋ฅ์ ๋ง๋ค์ด๋ธ๋ค.
ํ์ง๋ง ํ ์ด๋ธ์ ๋ฐ์ดํฐ๊ฐ ๊ณ์ ์์ด๋ ๊ตฌ์กฐ๋ผ๋ฉด 'FULL SCAN' ๋ฐฉ์์ ์๊ฐ์ด ์ง๋ ์๋ก ์ฑ๋ฅ์ด ๋ ๋๋น ์ง๋ค.
์ด๋ฐ ๊ฒฝ์ฐ์๋ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ์๋ผ๋ด๊ฑฐ๋ ํํฐ์ ์ ๋ต์ ์๋ฆฝํ ํ์๊ฐ ์๋ค.
๋๋ ์ค๊ฐ ์ง๊ณ ํ ์ด๋ธ ๋ฑ์ ํ์ฉํ๋ ๋ฐฉ์์ ๊ณ ๋ คํด์ผ ํ๋ค.
์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
1. ์ ์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋๋ค๋ฉด 'INDEX RANGE SCAN'์ด ์ ๋ฆฌํ๋ค.
2. ๋ง์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด์ผ ํ๋ค๋ฉด 'FULL SCAN'์ด ์ ๋ฆฌํ ์ ์๋ค.
3. ํ์ง๋ง 'FULL SCAN'์ ๋ฐ์ดํฐ๊ฐ ์์ผ์๋ก ์ฑ๋ฅ์ด ์ ์ฐจ ๋๋น ์ง๋ค. ํ ์ด๋ธ ๊ด๋ฆฌ ์ ๋ต์ด ํ์ํ๋ค.
๋ฐ๋ผ์ SQL ์ฑ๋ฅ์ ๋์ด๋ ค๋ ๋ชฉ์ ์ผ๋ก ๋ฌด์กฐ๊ฑด ์ธ๋ฑ์ค๋ฅผ ๋ง๋ค์ด์๋ ์ ๋๋ค.
์ธ๋ฑ์ค๋ฅผ ๋ง๋ค๊ธฐ ์ ์ ์๋ก์ด ์ธ๋ฑ์ค๊ฐ ๊ณผ์ฐ ์ฑ๋ฅ์ ๋์์ด ๋ ์ง๋ฅผ ํ๋จํด์ผ ํ๋ค.
'๐พ ๋ฐ์ดํฐ๋ฒ ์ด์ค > SQL BOOSTER' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SQL BOOSTER] 6-2. ๋จ์ผ ์ธ๋ฑ์ค (1) | 2024.06.09 |
---|---|
[SQL BOOSTER] 5-2. ์ฑ๋ฅ ๊ฐ์ ์ ์ํ ์ต์ํ์ ์ง์ (0) | 2024.03.22 |
[SQL BOOSTER] 5-1. ์คํ๊ณํ (0) | 2024.03.19 |
[SQL BOOSTER] 3-2. OUTER JOIN (0) | 2024.03.19 |
[SQL BOOSTER] 3-1. INNER JOIN (0) | 2024.03.19 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
Claire's Study Note
Hi.Claire