๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

TIL/๐Ÿงฌ DB

Index(์ƒ‰์ธ)

์ธ๋ฑ์Šค๋ž€, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ํ…Œ์ด๋ธ”์˜ ์—ด(Colunm)์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰ ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ๋‹ค.

์‰ฝ๊ฒŒ ๋งํ•ด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด์˜ ํ…Œ์ด๋ธ”์—์„œ ํŠน์ • ์—ด์— ๋Œ€ํ•œ ๊ฒ€์ƒ‰์„ ๋น ๋ฅด๊ฒŒ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค.

์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๊ฒ€์ƒ‰์ด ๋นจ๋ผ์ง€๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

 

ํŠน์ง•

  • ์ธ๋ฑ์Šค๋Š” ํ•ด๋‹น ์—ด์— ๋Œ€ํ•œ ์ •๋ ฌ๋œ ๋ชฉ๋ก์„ ๋งŒ๋“ ๋‹ค.
  • ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ๊ฒ€์ƒ‰ ์†๋„๊ฐ€ ํ–ฅ์ƒ๋œ๋‹ค.
  • ์ธ๋ฑ์Šค๋Š” ๋””์Šคํฌ ๊ณต๊ฐ„์„ ์ถ”๊ฐ€๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์ ์ ˆํ•œ ์—ด์— ๋Œ€ํ•ด์„œ๋งŒ ์ธ๋ฑ์Šค๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.
  • ์ธ๋ฑ์Šค๋ฅผ ์ง€๋‚˜์น˜๊ฒŒ ๋งŽ์ด ์ƒ์„ฑํ•˜๋ฉด ๋ฐ์ดํ„ฐ ์ž…๋ ฅ ๋ฐ ์‚ญ์ œ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค. (์—ญํšจ๊ณผ ๋ฐœ์ƒ ๊ฐ€๋Šฅ)
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋  ๋•Œ ์ธ๋ฑ์Šค ์—…๋ฐ์ดํŠธ ์ž‘์—…์ด ์ˆ˜ํ–‰๋œ๋‹ค.

 

์นผ๋Ÿผ์— ์ธ๋ฑ์Šค๋ฅผ ๊ฑฐ๋Š” ๊ฒƒ์— ๋Œ€ํ•œ ์žฅ๋‹จ์ 

  • ์žฅ์  : SELECT ์†๋„ ํ–ฅ์ƒ
    • ์ธ๋ฑ์Šค๋ฅผ ๊ฑธ๋ฉด ํ’€์Šค์บ”์ด ์•„๋‹ˆ๋ผ ์ข์€๋ฒ”์œ„๊ฒ€์ƒ‰ ์œผ๋กœ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.
      • ์ธ๋ฑ์Šค๊ฐ€ ์œ ๋‹ˆํฌ ์ธ๋ฑ์Šค๋ผ๋ฉด ์ข์€๋ฒ”์œ„๊ฒ€์ƒ‰ + ๋ฐœ๊ฒฌ์ฆ‰์‹œ๊ฒ€์ƒ‰์ข…๋ฃŒ ์˜ ํšจ๊ณผ๊นŒ์ง€ ๋ฐœ์ƒํ•œ๋‹ค.
  • ๋‹จ์  : INSERT, UPDATE, DELETE ์†๋„ ํ•˜๋ฝ
    • ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€, ์ˆ˜์ •, ์‚ญ์ œํ•  ๋•Œ ๋งˆ๋‹ค ๊ทธ์— ๋Œ€์‘๋˜๋Š” ์ƒ‰์ธ(INDEX) ๋ฐ์ดํ„ฐ๋„ ์ถ”๊ฐ€, ์ˆ˜์ •, ์‚ญ์ œ ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด ์–ธ์ œ ์ƒ‰์ธ์„ ๊ฑธ์–ด์•ผ ํ•˜๋Š”๊ฐ€?

  • ์‹œ์Šคํ…œ์˜ ์†๋„๊ฐ€ ๋А๋ ค์งˆ ๋•Œ
  • SLOW QUERY(๋А๋ฆฐ์ฝ”๋“œ ๊ฒ€์ถœ)์„ ์ฐพ์•„ ๋ถ„์„ํ•˜์—ฌ ์ธ๋ฑ์Šค๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๊ฑธ์–ด์ฃผ๋ฉด ๋œ๋‹ค.
  • ๋А๋ฆฐ ์ฟผ๋ฆฌ ํ•„ํ„ฐ๋ง ๊ธฐ์ˆ ์„ ์ด์šฉํ•˜๋ฉด, ์‰ฝ๊ฒŒ ์ฟผ๋ฆฌ ํŠœ๋‹์„ ํ†ตํ•œ ์†๋„ ํ–ฅ์ƒ ๊ฐ€๋Šฅ

 

์ธ๋ฑ์Šค ์ข…๋ฅ˜

  1. PRIMARY KEY : ์ฃผ ํ‚ค ์ธ๋ฑ์Šค
    • ์œ ๋‹ˆํฌ + NOT NULL
  2. UNIQUE KEY : ์œ ๋‹ˆํฌ ์ธ๋ฑ์Šค
    • ์œ ๋‹ˆํฌ
  3. NORMAL KEY : ์ผ๋ฐ˜ ์ธ๋ฑ์Šค
    • ์œ ๋‹ˆํฌ ์—†๋Š” ์ผ๋ฐ˜ ์ธ๋ฑ์Šค
  4. FULL TEXT : ํ’€ ํ…์ŠคํŠธ ์ธ๋ฑ์Šค
    • ๋ณธ๋ฌธ ๊ฒ€์ƒ‰์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ธ๋ฑ์Šค
    • ํ•œ๊ธ€์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.
      • ์—˜๋ผ์Šคํ‹ฑ ์„œ์น˜๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

 

UNIQUE INDEX

: ์ค‘๋ณต์ด ์—†๋Š” ์ธ๋ฑ์Šค๋กœ, PRIMARY KEY์™€ ์œ ์‚ฌํ•˜๋‹ค.

๊ณ ์œ ํ•œ ๊ฐ’์„ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ๊ฒ€์ƒ‰ ์‹œ ์ผ์น˜ํ•œ๋‹ค๋ฉด ์ถ”๊ฐ€ ๊ฒ€์ƒ‰์„ ํ•˜์ง€ ์•Š์•„ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ธ๋ฑ์Šค ์กฐํšŒ

SHOW INDEX FROM ํ…Œ์ด๋ธ”๋ช…;

 

์ธ๋ฑ์Šค ์ถ”๊ฐ€

ALTER TABLE ํ…Œ์ด๋ธ”๋ช… ADD (UNIQUE) INDEX ์ธ๋ฑ์Šค๋ช…;

or

CREATE TABLE `member` (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),
    regDate DATETIME NOT NULL,
    loginId CHAR(50) UNIQUE NOT NULL,    #์œ ๋‹ˆํฌ ์ธ๋ฑ์Šค ์ถ”๊ฐ€
    loginPw VARCHAR(100) NOT NULL,
    `name` CHAR(100) NOT NULL
);
  • loginID ์— UNIQUE ์„ค์ •์„ ํ†ตํ•ด UNIQUE INDEX ์ถ”๊ฐ€

 

์ธ๋ฑ์Šค ์‚ญ์ œ

ALTER TABLE ํ…Œ์ด๋ธ”๋ช… DROP INDEX ์ธ๋ฑ์Šค๋ช…;

 

 

Index์˜ ํ•„์š”์„ฑ

1. ๋”๋ฏธ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ

CREATE TABLE `member` (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),
    regDate DATETIME NOT NULL,
    loginId CHAR(50) NOT NULL,
    loginPw VARCHAR(100) NOT NULL,
    `name` CHAR(100) NOT NULL
);

-- ํ•ด๋‹น sql ๊ตฌ๋ฌธ์— from member ๋ฅผ ๋ถ™์ด๊ฒŒ ๋˜๋ฉด member์˜ ์ˆ˜ ๋งŒํผ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค. 
select now(), UUID(), 'pw', 'aaa'
	from member;

-- ์ด๋ ‡๊ฒŒ insert๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด **member์˜ ์ˆ˜๋งŒํผ data๊ฐ€ insert** ๋œ๋‹ค. 
-- 1->2->4->8 ์ด๋Ÿฐ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ์˜ ๊ฐฏ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ•œ๋‹ค. ๋”๋ฏธ ๋ฐ์ดํ„ฐ 100๋งŒ๊ฐœ๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž. 
insert into member(regDate, loginId, loginPw, `name`)
	select now(), UUID(), 'pw', 'aaa'
	from member;

→ index ์˜ ํ•„์š”์„ฑ์„ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด์„œ ๋”๋ฏธ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“œ๋Š” ์ฝ”๋“œ์ด๋‹ค.

  • ํ•˜๋‹จ์˜ insert SQL ๋ฌธ์„ ์•ฝ 10~20๋ฒˆ ์ •๋„ ๋ฐ˜๋ณตํ•ด์„œ 100๋งŒ ~ 400๋งŒ ๊ฐœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

 

2. select ์ฟผ๋ฆฌ ๋‚ ๋ฆฌ๊ธฐ

# ํšŒ์›์ˆ˜ ํ™•์ธ
select count(*) from member;

# ๊ฒ€์ƒ‰์†๋„ ํ™•์ธ
## ํžŒํŠธ : SQL_NO_CACHE
-- 4๋ฐฑ๋งŒ๊ฐœ์—์„œ ๋ฐ์ดํ„ฐ ์ฐพ๋Š”๋ฐ 2์ดˆ๊ฐ€ ๊ฑธ๋ ธ๋‹ค... 2๋ฐฑ๋งŒ๊ฐœ์—์„œ๋Š” 1์ดˆ ๊ฑธ๋ฆผ  
SELECT SQL_NO_CACHE * FROM `member`
	WHERE loginId = 'user1';
  • ๊ธฐ์กด์˜ SQL๋ฌธ์ œ๋ฅผ ํ’€ ๋•Œ ํŠœํ”Œ(row)์ด 5๊ฐœ ๋ฏธ๋งŒ ์ด์˜€๋‹ค. ๊ทธ๋ž˜์„œ ๊ฒฐ๊ณผ๊ฐ€ 0์ดˆ์— ๊ทผ์ ‘ํ•˜๊ฒŒ ๊ฑธ๋ ธ๋‹ค.
  • ์ง€๊ธˆ 100~400๋งŒ๊ฐœ์˜ ๋ฐ์ดํ„ฐ ์†์—์„œ ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ์นด์šดํŒ… ํ•˜๊ณ  ํŠน์ • user๋ฅผ ์ฐพ๋Š” ์ฟผ๋ฆฌ๋ฌธ์„ ๋‚ ๋ ธ์„ ๋•Œ 2์ดˆ ์ •๋„๊ฐ€ ๊ฑธ๋ฆฐ๋‹ค.

→ ๊ทธ๋ž˜์„œ INDEX๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์‹ค์ƒํ™œ์—์„œ ๋ฐฑ๊ณผ์‚ฌ์ „์—์„œ ๋‹จ์–ด๋ฅผ ์ฐพ์„ ๋•Œ, ๋ฐฑ๊ณผ์‚ฌ์ „์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๋’ค์ง€๋ฉด์„œ ์›ํ•˜๋Š” ๋‹จ์–ด์˜ ๋œป์„ ์ฐพ์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ใ„ฑ ใ„ด ใ„ท ใ„น ์ด๋ ‡๊ฒŒ Indexing์ด ๋˜์–ด์žˆ๋Š” ๋ถ€๋ถ„๋ถ€ํ„ฐ ์ฐพ์„ ๊ฒƒ์ด๋‹ค. DataBase์—์„œ๋„ Index๊ฐ€ ์กด์žฌํ•œ๋‹ค.

 

3. Index ์‚ฌ์šฉํ•˜๊ธฐ

# ์œ ๋‹ˆํฌ ์ธ๋ฑ์Šค๋ฅผ loginID ์นผ๋Ÿผ์— ๊ฑธ๊ธฐ
ALTER TABLE `member` ADD UNIQUE INDEX (`loginId`); 
show index from member; -- member ํ…Œ์ด๋ธ”์— ๊ฑธ๋ ค์žˆ๋Š” index ๊ฐฏ์ˆ˜ ํ™•์ธ. ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” 1๊ฐœ ๋ฟ. primary key์— index๊ฐ€ ๊ฑธ๋ ค์žˆ๋‹ค.

# ๊ฒ€์ƒ‰์†๋„ ํ™•์ธ, loginId ๊ฐ€ 'user1' ์ธ ํšŒ์› ๊ฒ€์ƒ‰
-- Wow... loginId์— index๋ฅผ ๊ฑธ์—ˆ๋”๋‹ˆ ๊ฒ€์ƒ‰์†๋„๊ฐ€ 0์— ์ˆ˜๋ ดํ•œ๋‹ค..  
SELECT SQL_NO_CACHE * FROM `member`
	WHERE loginId = 'user1';
  • Index ๋ฅผ ๋“ฑ๋กํ•˜๊ณ  select ๊ตฌ๋ฌธ์œผ๋กœ ์กฐํšŒ๋ฅผ ํ•ด๋ณด์ž.
  • ๋ฐ์ดํ„ฐ๊ฐ€ 5๊ฐœ๋ฏธ๋งŒ ์žˆ์—ˆ์„ ๋•Œ์™€ ๋น„์Šทํ•œ ์†๋„๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.