데이터베이스 인덱스 추가
GitLab 데이터베이스에 인덱스를 추가하는 방법과 시기, 비동기 인덱스 생성 및 삭제, 네이밍 규칙을 설명합니다.
인덱스는 데이터베이스 쿼리 속도를 높이는 데 사용할 수 있지만, 새 인덱스는 언제 추가해야 할까요? 전통적으로 이 질문에 대한 답은 데이터를 필터링하거나 조인하는 데 사용되는 모든 칼럼에 인덱스를 추가하는 것이었습니다. 예를 들어, 다음 쿼리를 살펴보겠습니다: SELECT * FROM projects WHERE user_id = 2; 여기서는 user_id 칼럼으로 필터링하므로, 개발자가 이 칼럼에 인덱스를 추가하기로 결정할 수 있습니다. 위의 방식으로 칼럼에 인덱스를 추가하는 것이 특정 경우에는 의미가 있을 수 있지만, 실제로는 부정적인 영향을 미칠 수 있습니다. 테이블에 데이터를 쓸 때마다 기존의 모든 인덱스도 업데이트되어야 합니다. 인덱스가 많을수록 이 과정이 잠재적으로 느려질 수 있습니다. 인덱스는 인덱싱된 데이터의 양과 인덱스 유형에 따라 상당한 디스크 공간을 차지할 수도 있습니다. 예를 들어, PostgreSQL은 일반 B-tree 인덱스로는 인덱싱할 수 없는 특정 데이터 유형을 인덱싱하는 데 사용할 수 있는 GIN 인덱스를 제공합니다. 그러나 이러한 인덱스는 일반적으로 B-tree 인덱스에 비해 더 많은 데이터를 차지하고 업데이트 속도가 느립니다. 이 모든 것을 고려했을 때, 새 인덱스를 추가할 때 다음 사항을 고려하는 것이 중요합니다: 새로운 쿼리가 기존 인덱스를 최대한 재사용하는가? 인덱스를 사용하는 것이 테이블의 행을 순회하는 것보다 빠를 만큼 충분한 데이터가 있는가? 인덱스를 유지하는 오버헤드가 쿼리 실행 시간 단축을 정당화할 만큼의 가치가 있는가? 어떤 상황에서는 인덱스가 필요하지 않을 수 있습니다: 테이블이 작고( 1,000 개 미만의 레코드) 기하급수적으로 크기가 증가할 것으로 예상되지 않는 경우. 기존 인덱스가 충분히 많은 행을 필터링하는 경우. 인덱스 추가 후 쿼리 실행 시간 단축이 크지 않은 경우. 또한 와이드 인덱스는 쿼리의 모든 필터 조건과 일치할 필요가 없습니다. 인덱스 조회의 선택도(selectivity)가 충분히 작을 만큼 칼럼을 포함하기만 하면 됩니다. 쿼리 재사용 # 첫 번째 단계는 쿼리가 기존 인덱스를 최대한 재사용하도록 하는 것입니다. 예를 들어, 다음 쿼리를 살펴보겠습니다: SELECT * FROM todos WHERE user_id = 123 AND state = 'open'; 이제 user_id 칼럼에는 인덱스가 있지만 state 칼럼에는 인덱스가 없다고 가정해 봅니다. state 에 인덱스가 없기 때문에 이 쿼리의 성능이 나쁠 것이라고 생각할 수 있습니다. 실제로는 user_id 의 인덱스가 충분한 행을 필터링할 수 있으므로 쿼리가 충분히 잘 수행될 수 있습니다. 인덱스가 재사용되는지 확인하는 가장 좋은 방법은 EXPLAIN ANALYZE 를 사용하여 쿼리를 실행하는 것입니다. 조인된 테이블과 필터링에 사용되는 칼럼에 따라 추가 인덱스가 별로 도움이 되지 않을 수도 있습니다. 요약하면: 기존 인덱스를 최대한 재사용하는 방식으로 쿼리를 작성하세요. EXPLAIN ANALYZE 를 사용하