공부/인프런 - Rookiss

Part 5-2-14. SQL 입문 : INDEX

셩잇님 2024. 2. 13. 17:58
반응형

 

 

💅 SQL 입문

 

 지난 시간에는 정규화를 통해 데이터베이스 내 중복된 데이터를 분리하여 관리하는 방법에 대해서 알아보았다. 이번 시간에는 INDEX(=색인) 이라는 개념을 통해 데이터베이스 내 엄청나게 많은 데이터속에서 보다 빠르게 조회하는 방법과 인덱스의 종류인 클러스터, 논 클러스터형에 대해서 알아보는 시간을 가진다.

 


 

📖 INDEX

 

 인덱스는 중요도를 평가할 수 없을 정도로 데이터베이스에서 매우 중요한 개념이다. 애시당초 인덱스를 이해 못한다고 하면 데이터베이스 자체를 사용하는게 큰 의미가 없을 정도로 인덱스는 굉장히 중요하다. 이러한 중요성 덕분에 데이터베이스  관련 면접을 본다고하면 0번째 질문이 인덱스에 관한 내용일 정도로 인덱스는 매우 중요하다.

 

 위키백과에 따르면 인덱스(영어: index)는 데이터베이스 분야에 있어서 테이블에 대한 동작의 속도를 높여주는 자료 구조를 일컫는다. 라고 나와있다. 이렇게 단순 개념을 글로만 작성한다면 이해하기 힘들 수 있으므로 간단한 예를 통해 인덱스의 개념을 이해하고 알아보자.

 


 

 전공책이던 자격증 책이던, 성경책이던 책을 찾아서 뒤져보자. 정보처리기사 책으로 예를 든다면 '데드락'이라는 단어를 찾고자 하면, 책에 모든 부분을 다 하나하나 찾아볼 필요 없이 부록으로 실린 색인을 찾아보면 '데드락'이 어느 페이지에 있는지 쉽게 알 수 있을 것이다.

 

 INDEX가 바로 이러한 색인 역할을 한다. 지난 시간 정규화에 대해 학습하고, 테이블을 적절히 나누는 방법을 터득했다.

 

 

 지금 당장은 플레이어의 테이블에 사용자가 두 명이라 상관이 없겠지만, 게임이 너무나도 흥행해 유저 수가 천만명이라고 가정해보자. 이 떄 게임을 할면서 귓속말 기능을 사용해 상대방에게 귓속말을 할 때  상대가 접속 중인지 아닌지 알기 위해선 데이터베이스 내에서 상대의 접속 상태를 알 필요가 있다.

바로 이러할 때에 INDEX가 필요한 것이다. 만약 INDEX가 없다면 정보처리기사 책을 앞에서 하나하나 보는 것 처럼 수천만명의 유저들 DB를 하나하나 찾아가면서 봐야 할 것이다. 

 


 

모든 열에 INDEX를 걸면 되지 않을까?


 INDEX에 이렇게 중요하고 필요하다면 모든 열에 INDEX를 걸면 되지 않을까? 라는 의문은 자연스럽게 들 것이다. 그렇지만 INDEX를 사용하면 오히려 독이 되는 경우도 있다.

 

 위 예제 class 열에 INDEX를 사용한다고 가정하자. 마법사에 대한 정보를 찾기 위해서 검색한다면 수백만 유저의 마법사 클래스 결과가 나올 것이다. 이는 마치 '데드락'을 정보처리기사 책에서 찾으려고 색인을 펼쳤더니 온갖 페이지에서 데드락을 나열하고 있는 상황과 같은 것이다. 

 

 따라서 INDEX는 단어의 종류가 많되 겹치는게 별로 없어야 최적의 성능을 낸다.

 


 

그렇다면 PRIMARY KEY를 INDEX로 사용하면 되지 않을까?

 

 사실 이는 어느정도 맞는 말이다. 그러나 여기서 조금 보완을 해야될 내용은 INDEX에서도 종류가 있다는 것이다. INDEX는 다음과 같이 두 종류로 나누어진다.

 

Clustered Index : 실제 데이터가 정렬된 상태로 저장됨 (물리적인 데이터 저장 순서의 기준) ➡️ 영한 사전
Non-Clustered Index : 따로 관리하는 일종의 LOOK UP 테이블 ➡️ 정보처리기사책의 부록 (색인)

 

Primary Key는 대부분 Clustered Index이며, 테이블 당 1개만 존재하고 제일 좋고 빠른 존재이다.

 


 

실습을 해보자. 😎

 

이제 지난 시간에 만든 GameDB 데이터베이스의 accounts 테이블로 간단하게 Index를 만들어보자. 우선 Primary Key도 Index 이므로, 아래와 같이 쿼리를 작성하고 실행하 accountId 열에 이를 추가해주자.

 

ALTER TABLE accounts
ADD CONSTRAINT PK_Account PRIMARY KEY (accountId);

 

테이블을 새로고침 하면

 

 

다음과 같이 Key에도 속하고, 클러스터형 인덱스에 속하는 것을 볼 수 있다. 

 우리의 GameDB 테이블에선 accountName(계정 이름)도 인덱스에 꽤나 적절한 열이라고 볼 수 있다. 대부분의 게임에선 닉네임도 중복을 허용하지 않으므로 이럴때에는 Non-Clustered Index로 추가해주면 좋을 것이다.

 

CREATE INDEX i1 ON accounts(accountName);
--accounts 테이블 내 accountName 열에 i1이라는 Index를 추가한다.

 

똑같이 새로고침을 한다면, 인덱스에 비클러스터형 i1이 생성될 것이고, 키에는 생성이 안된 것을 볼 수 있다.


마지막으로 생성한 인덱스를 제거하려면 다음과 같은 명령어를 사용하면 된다.

 

DROP INDEX accounts.i1;

 

 

 

반응형