[면접공부] - db (feat.gpt) (4)

반응형
반응형

Clustered Index / Non-Clustered Index 에 대해 설명해주세요.
IN 절에 들어갈 수 있는 최대 항목 수에 대해 알고 계실까요?
인덱스를 타지 않거나 혹은 기대하는 성능을 못내는 경우는?
트랜잭션 격리 수준에 대해 설명해주세요.

이렇게 4문제를 정리를 하려고 한다. 
눈에 띄는건 격리 수준에 대해 설명은 일부러 또 넣었다. 왜냐하면 굉장히 중요하다고 생각했기 때문이다.

암튼 내가 제일먼저 학습을 해야 하는 부분은 클러스터라는 개념이다.
과연 클러스터라는 건 무엇일까?
찾아보니 클러스터는 군집,집단이라는 뜻이다.
이걸 생각해보고 첫번째 질문부터 다시 생각해보자.
첫번째 질문은 클러스터 인덱스와 논 클러스터 인덱스를 뜻한다.
클러스터 인덱스는 군집의 대빵이 될 수 있는 인덱스로 자동적으로 정렬이 된다는 특징이 있다. 왜냐하면 클러스터의 인덱스를 찾아야 되기 때문이다. 그렇다면 논 클러스터 인덱스는 어떤걸까? 바로 군집의 대상의 되지 않는 인덱스를 뜻한다. 그러니까 정렬이 안되는 느낌이다.
이제 gpt는 어떤 답변을 하는지 보자.

클러스터형 인덱스는 실제 데이터가 인덱스 자체에 정렬되어 저장되는 구조이기 때문에, 범위 조회나 정렬이 많은 쿼리에서 유리합니다. 반면, 비클러스터형 인덱스는 인덱스와 데이터가 분리되어 있어 다양한 조건으로 여러 개의 인덱스를 만들 수 있다는 장점이 있지만, 추가적인 Lookup 비용이 발생할 수 있습니다. 실무에서는 조회 쿼리 패턴과 자주 사용되는 컬럼을 기준으로 적절히 선택합니다.

이것을 확장하면 커버링 인덱스라는 것을 생각할 수 있는데 요건 내가 생각기에는 복합 인덱스라 생각한다.
커버링이 되었다는건 인덱스(조회)만으로 충분히 커버가 된다는 뜻이된다. 그렇다고 무분별하게 인덱스를 사용하게 되면 오히려 성능이 떨어지는 걸로 알고 있다. 그러니 주의를 기울려서 작성하자.(여기에는 커버링 인덱스에 대해 작성하지는 않았다.)

IN 절에 들어갈 수 있는 최대 항목 수에 대해 알고 계실까요? 두 번째 이 질문은 굉장히 애매하다. 기본갯수가 200개라고 하는데 그게 중요할까? 기본갯수가 200개인게 그렇게 중요한걸까? gpt에 물어보니 200개는 아니라고 한다 정확한 내용은 아니기에.. 단지 프레임워크에서 막아놨다고 한다. 근데 개인적으로 요 질문은 안나올거라 예상한다. 왜냐하면 뭔가 그렇다. 만약 200라고 한다면 어떻게 쿼리를 가져가면 좋을지 물어보는게 더 좋지 않을까 라는 생각이 든다.

💡 1. 대안 설계 방향

✅ 1) 여러 번 나누어 조회

  • IN 절을 200개씩 끊어서 여러 번 쿼리를 날린 뒤, 애플리케이션 단에서 결과를 합치는 방법이 있어요.
 
SELECT * FROM member WHERE id IN (1, 2, ..., 200);
SELECT * FROM member WHERE id IN (201, ..., 400); -- 결과를 합쳐서 처리

보통 이걸 배치 쿼리 처리라고 부릅니다. MyBatis나 JPA에서도 흔히 쓰여요.


✅ 2) 임시 테이블(또는 테이블 변수) 사용

  • ID 리스트가 너무 많을 땐, 임시 테이블에 넣고 조인하는 방식이 안정적이에요.
 
-- temp_ids라는 테이블을 만들어서 데이터를 넣고 SELECT m.* FROM member m JOIN temp_ids t ON m.id = t.id;

임시 테이블은 쿼리 성능에도 유리하고, DB가 IN절보다 조인 최적화를 잘 해줄 수 있어요.


✅ 3) JSON 형태로 넘기고, 파싱

MySQL 5.7 이상이라면 JSON_TABLE 같은 기능으로 JSON 배열을 파싱해서 처리할 수도 있어요. 다만 복잡한 로직에선 성능 이슈가 생길 수 있어요.


✅ 4) 애플리케이션 단에서 필터링

  • 정말 어쩔 수 없다면 전체 데이터를 가져와서 자바 등에서 필터링하는 방법도 있지만… 이건 데이터 양이 적을 때만.

🧠 전략 선택 기준

전략데이터 양성능복잡도사용 시점
다중 IN 소~중 보통 쉬움 빠르게 처리할 때
임시 테이블 중~대 좋음 보통 안정적 처리 원할 때
JSON 파싱 낮음 어려움 MySQL JSON 가능 시
애플리케이션 필터링 낮음 쉬움 임시처리, 프로토타입

✨ 결론

200개 제한이 있다면, 가장 실용적인 방법은
"IN절을 나누어 실행하거나, 임시 테이블을 활용한 조인 처리"입니다.

확인을 해보니

MySQL 8.x에서 IN 절의 항목 수에는 사실상 제한이 없지만 (이론적으로는 수만 개도 가능), 쿼리 크기 및 성능 측면의 현실적인 한계가 존재합니다. 패킷 크기 제한을 넘으면 오류가 발생하고, 약 200개를 넘어서면 Optimizer 동작이 달라지며, 지나치게 많은 값은 오히려 풀스캔을 유발할 수 있습니다. 따라서 수십~수백 개 수준으로 사용하는 것을 권장하며, 그 이상 필요할 경우 쿼리 구조를 재고하거나 시스템 변수를 튜닝하는 접근이 필요합니다.
라고 한다. 즉 200개는 최대 갯수가 아니라 권장 최대 갯수였다.

상황에 따라 다르긴 하지만, 운영 환경에선 임시 테이블 방식이 가장 안정적이고 확장성도 좋아요.
이런식으로 작성할 수 있다고 한다.

다음 질문 인덱스를 타지 않거나 혹은 기대하는 성능을 못내는 경우는?이건데
이거는 간단하다. 인덱스는 그걸로 조회를 하는 경우 의미가 있는데 그렇지 않는 경우 인덱스를 타지 않고 몇몇의 DB에서는 NULL값은 인덱스를 안탄다고 한다. 그리고 기대하는 성능을 못내는 경우는 인덱스로 조회하지 않는 경우와 복합 인덱스를 잘 못된 방법으로 설정하는 방법이다. 잘못된 방법이란 복합 인덱스는 왼쪽부터 실행이 되어지고 카디널리티가 많은 수부터 작성을 해야 한다. 또한 인덱스가 많이 걸려있다고 해서 굳이 그 인덱스를 탈 필요가 없다면 의미가 없다고 생각한다.

네, 인덱스는 정확한 조건에서만 효과를 발휘하기 때문에 몇 가지 상황에서는 인덱스를 타지 않거나 기대한 만큼의 성능이 나오지 않는 경우가 있습니다.

첫 번째로, 조회 조건이 인덱스를 타지 않는 방식일 때입니다.
예를 들어, 인덱스가 걸린 컬럼에 대해 함수, 계산식, 또는 LIKE '%xxx' 같은 조건을 쓰면 인덱스가 무시되고 전체 테이블 스캔이 발생할 수 있습니다.
그리고 일부 DBMS에서는 NULL 값에 대해 인덱스를 활용하지 않기도 합니다.

두 번째는 복합 인덱스를 잘못 사용한 경우입니다.
복합 인덱스는 왼쪽부터 순차적으로 조건이 걸려야 인덱스를 잘 타는데, 중간 컬럼부터 조건을 걸면 옵티마이저가 인덱스를 무시할 수 있습니다.
예를 들어 (region, gender, age) 순서의 인덱스에서 gender만 조건에 쓰면 제대로 활용되지 않습니다.

세 번째는 카디널리티가 낮은 컬럼에 인덱스를 걸었을 때입니다.
카디널리티가 낮으면 결국 읽을 데이터가 많기 때문에, 인덱스를 써도 성능이 잘 나오지 않습니다.
오히려 풀스캔이 더 빠른 경우도 있어서, 옵티마이저가 인덱스를 선택하지 않기도 합니다.

마지막으로는 과도한 인덱스 설계입니다.
인덱스가 많으면 조회는 빠를 수 있지만, insert/update/delete 시마다 인덱스를 유지해야 해서 성능이 크게 떨어질 수 있습니다.

그래서 저는 인덱스 설계 시, 단순히 “있으면 좋다”가 아니라 조회 패턴, 카디널리티, 데이터 양, 인덱스 순서까지 함께 고려해서 설계하려고 노력하고 있습니다.

또 왔다. 트랜잭션 격리 수준에 대해 설명해주세요. 이거에 대해 어제도 물어보고 계속 물어보는 단골 질문이다.
이걸 어떻게 답변을 할까?
격리 수준은 총 4가지로 되어 있다.
1. Read Uncommitted (읽기 미확정)
2.Read Committed (읽기 확정)   
3. Repeatable Read (반복 가능 읽기) ← MySQL(InnoDB)의 기본값
4. Serializable (직렬화)

  • MySQL(InnoDB)의 기본값은 Repeatable Read
  • Oracle의 기본값은 Read Committed
  • 실제 서비스에선 주로 Read Committed를 많이 씀 (성능과 일관성의 균형)
  • Phantom Read 방지를 위해 Gap Lock이나 MVCC를 활용하기도 함 (MySQL)


MVCC는 Multi-Version Concurrency Control의 약자로,
말 그대로 "하나의 데이터를 여러 버전으로 관리하면서 동시성 문제를 해결하는 방법"입니다.

오늘은 여기까지만하자 원래 6문제를 하려고 했는데 너무 힘들다..

 

 

반응형

댓글

Designed by JB FACTORY