-
Notifications
You must be signed in to change notification settings - Fork 1
갑자기 테이블 하나 추가, DB 인덱싱
우리는 원래 Playlist 라는 재생 목록 테이블에서 “최근 재생 목록” 을 하나의 playlist 로 관리하고 있었다.
그런데 사용자가 노래를 재생했을 때 최근 재생 목록에서 해당 노래를 추가하거나 최상단으로 update를 해야하는데, 이때 재생한 시간을 담는 컬럼이 필요해진다. 그런데 그 컬럼은 오직 최근 재생 목록에만 필요하고 다른 재생 목록에는 필요가 없다.
그래서 최근 재생 목록을 playlist 로 관리하는 것은 맞지 않다고 판단했고 따로 테이블을 만들기로 결정했다.
그래서 이렇게 바뀌게 됐다.
최근 재생 목록을 관리하는 Recent_Played 테이블이 Music 과 User 테이블 사이에서 관계를 가지고 있는 것을 볼 수 있다. 이 테이블 안에는 어떤 사용자가 언제 어떤 음악을 들었는지를 저장하기 위해 music_id, user_id, played_at 컬럼을 가지고 저장한다.
그리고 음악과 재생 목록 사이에 관계를 가졌던 Music_Playlist 테이블에서는 updated_at 컬럼을 created_at 으로 바꾸면서 컬럼 이름이 더 직관적이고 자기 역할에 맞는 이름을 가지게 되었다.
인덱스란 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다.
만약 우리가 책에서 원하는 내용을 찾는다고 하면, 책의 모든 페이지를 찾아 보는것은 오랜 시간이 걸린다. 그렇기 때문에 책의 저자들은 책의 맨 앞 또는 맨 뒤에 색인을 추가하는데, 데이터베이스의 index는 책의 색인과 같다. 데이터베이스에서도 테이블의 모든 데이터를 검색하면 시간이 오래 걸리기 때문에 데이터와 데이터의 위치를 포함한 자료구조를 생성하여 빠르게 조회할 수 있도록 돕고 있다.
인덱스를 활용하면 SELECT 외에도 UPDATE 나 DELETE 의 성능이 같이 향상된다. 왜냐하면 해당 연산도 대상을 조회하는 작업이 먼저 수행되어야 하기 때문이다.
아무래도 서비스를 만들다보면 조회 API 를 많이 만들 수밖에 없고, 쿼리문도 SELECT 가 큰 비중을 차지하게 된다. 그래서 빈번하게 발행하는 컬럼에 대해서는 인덱스를 만들어줘서 조회 속도를 향상해줘야 한다고 생각했다.
코드를 잘 작성해서 빠르게 만드는 것도 물론 중요하지만 DB 쿼리의 속도를 향상시키는 과정도 필수적이다!
인덱스를 추가할수록 그다음으로 많이 발생하는 INSERT 문의 성능이 안 좋아진다는 단점이 있지만, INSERT 문보다 SELECT 문이 훨씬 많고 유저, 음악 등 데이터가 훨씬 많은 상황을 고려하면 인덱스를 만들어주는 것이 맞다고 판단했다.
인덱싱을 하기 좋은 컬럼의 기준에 대해서 멘토링 시간에 멘토님께 질문을 했다. week5 멘토링 일지
-
조회 횟수가 많을수록
-
테이블의 행이 많을수록
-
cardinality 가 높을수록
(* 특정 데이터 집합의 유닠한 값의 개수)
그리고 데이터가 많지 않은 지금 시점에 실제로 오래 걸리는 쿼리문이 뭔지, 인덱스를 어디에 걸어주면 좋을지 직접 확인하는 방법이 있는지 질문했다.
멘토님께서는 대량의 mock 데이터를 넣지 않는 이상 힘들다고 하셨고 데이터가 많은 상황을 상상하면서 인덱스의 효과를 예상하면서 걸어주는 방법밖에 없다고 하셨다.
그래서 우리가 위의 기준에 따라서 인덱스를 만들어주기로 결정한 컬럼들은 아래와 같다.
- user_id
- played_at
- user_id, music_id 복합
- none
- created_at
- genre (일단 X, 추후 생각)
- user_id
- playlist_id
- created_at
보통(우리) 서비스에서는 각 데이터의 id (Primary Key) 로 조회가 이루어진다. 따라서 직접 추가해줄 인덱스가 많지는 않았다.
User 테이블에서는 오직 PK인 user_id 로만 조회가 이루어지기 때문에 추가해주지 않았다. 그리고 각 테이블에서 조회가 많이 이루어지는 컬럼들에 대해서 인덱스를 만들어줬는다. 조금 특이한 것은 사용자가 특정 노래를 재생한 적이 있는지 조회하는 로직에서 user_id, music_id 를 AND 로 묶에서 WHERE 절에서 사용하는 경우가 빈번하기 때문에 복합 인덱스를 만들어줬다.
- 프로젝트 생성
- 프로젝트 구조
- PR에 대한 단위 테스트 자동화
- 역/직렬화 라이브러리 비교
- Github Release 자동화
- Firebase App 배포 자동화
- 플러그인을 이용하여 공통 설정 없애기
- Timber 라이브러리를 사용한 이유
- 네트워크 예외 처리
- Kotest 도입기