Open yunyechan9893 opened 2 weeks ago
1. 클러스터링 인덱스를 생성하는 것보다 auto_increment를 사용하지 않을 때의 성능 문제를 말씀드린 거였습니다. MySQL 과 MariaDB의 PK는 클러스터링 인덱스로 사용되다 보니 insert, update 등에서 auto_increment나 순차적으로 커지는 방향으로 저장하지 않으면 auto_increment를 사용할 때보다 성능이 좋지 않습니다. 그래서 uuid로 pk를 사용하는 경우에도 성능상 문제가 있어 사용하지 않거나 timestamp 등이 있는 버전을 이용해 insert시 시간순서로 정렬된 것을 사용합니다.
이 테이블의 특성상 board가 새롭게 증가할 때마다 새롭게 최대 3개의 insert가 발생하고 새롭게 생긴 board에 맞춰 전체 상품에서 유사도를 다시 계산해서 board를 바꿔주는 update가 발생합니다.
관련 블로그: uuid를 pk로 사용했을 때의 단점(블로그의 1번 목차를 봐주시면 좋을 것 같습니다) 클러스터링 인덱스 저장 방식에 관련된 블로그
그래서 복합키로 PK를 구성했을 때 성능상의 문제가 정말 없는지 다시 확인 부탁드립니다.
2번의 경우 정확한 자릿수 기준을 물어보고 지정하는 게 좋아보입니다 (17,16)이면 소수점 제외하고는 1의 자리수까지만 사용이 가능한데 그렇게 설정해도 괜찮은지 확인이 필요합니다.
3번의 경우 저는 이렇게 생각을 했습니다.
관련 블로그와 chat gpt 답변 같이 첨부합니다.
전체적으로 말씀을 드리자면 어떤 선택을 내릴 때 기존에 내린 선택과 다를 때 이 방법이 여러 측면에서 유의미한가? 를 한번 더 고민해주시면 좋을 것 같다는 생각이 들었습니다. 저희 RealMySQL을 스터디하는 만큼 개발을 할 때도 데이터 타입과 PK 설정, 인덱스에 대한 고민도 잘 묻어나면 좋을 것 같다는 생각입니다.
1. Auto Increment와 복합키 선택에 대한 고려 사항 현재 이 테이블의 데이터 삽입 및 업데이트가 빈번히 일어나는 것이 아니라, 일괄적으로 수행된다는 점을 고려할 때, Auto Increment보다는 복합키를 선택하는 것이 적절한 것 같습니다. 말씀하신 바와 같이, UUID를 사용할 경우 공간을 많이 차지할 뿐만 아니라, 랜덤 값 생성으로 인해 B-Tree 인덱스가 Leaf 노드의 맨 끝이 아닌 중간에 생성되기 때문에 성능 저하의 원인이 될 수 있습니다.
또한, 이 테이블에서 특정 query_item을 조회하거나 rank를 기준으로 정렬해야 한다는 점에서, 복합키 사용을 통해 조회 효율성을 높일 수 있습니다.
결과적으로, 삽입과 업데이트 빈도가 낮고 특정 조건과 정렬을 기반으로 조회가 필요하다는 상황을 감안한다면 현재 설계는 적절하다고 판단했습니다!
3. VARCHAR(255) 사용에 대한 판단 근거 과거에는 char와 varchar의 성능 차이가 중요하게 고려되었으나, 최근 소프트웨어 성능이 향상됨에 따라 이 차이가 미미하다는 의견이 있습니다. 확장성을 고려해 varchar(255)를 사용했으며, 길이가 255를 넘지 않는다면 저장 공간 낭비도 줄일 수 있습니다.
추가로, varchar 컬럼에 인덱스를 거는 경우에 발생할 수 있는 잠재적인 문제를 언급해 주셨는데, 이 또한 설계에 있어 중요한 고려사항이라 생각됩니다. 다만, 이 테이블에서는 enum 타입의 두 컬럼을 인덱스로 걸 일이 없다고 판단해 이 문제 역시 크게 우려할 필요는 없어 보입니다. 만약 varchar의 길이가 255를 초과해야 하는 상황이 발생한다면, 다른 저장 방식을 고려하는 것이 바람직하다는 의견에 전적으로 동의합니다
말씀해주신 부분 확인하고 있는데 복합키로 생성한 인덱스와 query_item만을 인덱스로 사용한 결과(explain)이 동일하게 나타나고 있습니다 좀 더 확인해봐야겠지만 rank의 범위로 인한 문제일 가능성이 큽니다. 작은 범위이기 때문에 MySQL 효율적이라고 판단하지 않아 타지 않는 것으로 보입니다(1~3까지의 rank만이 존재) 그리고 업데이트 될 일이 거의 없다고 말씀해주셨는데 이건 확실하진 않습니다
제가 uuid를 pk로 만들 경우에 대한 문제점을 복합키를 사용할 때 동일하게 나타날 수 있다고 언급은 했는데 varchar 컬럼에 인덱스를 거는 경우에 발생하는 문제점을 언급을 했었나요? enum과 관련해서? 다시 읽어봐도 못찾겠어서 질문드립니다.
추가로 varchar(255)의 사용 같은 경우 미미하다라고 판단을 할 수는 있지만 바로 디폴트 값을 쓰지 말고 한번 생각해볼 필요는 있다를 더 강조하고 싶습니다. 어떤 값이나 선택을 했을 때 대안을 생각을 해보고 결정하는 것과 바로 결정하는 것과는 차이가 있다고 생각해서 다시 강조드립니다. 255글자까지 안쓰는데 20글자로 제한하는 게 더 효율적이지 않나? 라는 생각을 해보고 실제로 돌려보는 것과 돌려보지 않는 것에는 큰 차이가 있다고 생각합니다.
1. id를 AutoIncrease 했을 경우
2. query_item를 PK로 설정하는 경우
3. rank는 서버 단에서 순위를 결정하지 않습니다
4. 판매자 유입이 되어 판매자가 게시글을 올리는 경우
5. 작은 범위이기 때문에 MySQL 효율적이라고 판단
6. 게시글 업로드 시 3개의 추천 데이터 insert
7. varchar 컬럼에 인덱스를 거는 경우에 발생하는 문제점을 언급을 했었나요?
8. varchar(255)의 사용 같은 경우 미미하다라고 판단을 할 수는 있지만 바로 디폴트 값을 쓰지 말고 한번 생각해볼 필요는 있다를 더 강조하고 싶습니다.
이러한 문제 때문에 이렇게 사용하는 게 좋겠다 라고 전달을 드리고 있지만 글이다 보니 감정이 제대로 전달되는 것 같지 않아 남깁니다! 혹시 감정 상하셨다면 그렇게 느끼지 않으셨으면 좋겠습니다!
이전에 제가 댓글에서 작성한 부분에서는 직접 예찬님이 말씀하신대로 인덱스를 타는지 보며 성능 이점이 있는지 저도 체크하고 전달하는 과정에서 설명해주신 부분과 다른 부분이 있어서 확인을 부탁드렸던 거에요!
이전 댓글에서 rank도 index를 타는 부분
또한, 이 테이블에서 특정 query_item을 조회하거나 rank를 기준으로 정렬해야 한다는 점에서, 복합키 사용을 통해 조회 효율성을 높일 수 있습니다.
복합키로 설정했을 때 query_item은 타지만 rank 쪽은 타지 않는 것으로 보여 다시 확인을 요청드린 부분입니다. 실제로 pk auto_increment 생성하고 query_item 에만 index를 생성했을 때의 결과와 같아(explain을 사용해서 봤을 때) 실제로 위 방법이 효율적이더라도 예찬님이 적어주신 부분과 다른 부분이 있어 확인이 필요하다는 것을 언급드린 부분이었습니다.
그리고 실제로 query_item에만 index를 걸면 되는 부분이라면 복합키를 걸어서 삽입 시 손해를 보는 부분과 pk를 auto_increment로 만들고 query_item에만 index를 거는 방식과 다시 비교해 생각해볼 필요는 있다고 생각해서 첫 번째로 이전 댓글에 언급했던 건데 작성 중에 태스크가 들어와서 조금 급하게 마무리를 짓느라 제대로 전달이 안된 부분이 있는 것 같아 보입니다.
varchar 부분에 대해서는 제가 적절한 예시를 전달하지 못한 것 같아 조금 더 찾아보았습니다. DB를 설계하는 입장에서 가능하면 효율을 보기 위해, 그리고 DB 삽입의 규칙을 서비스에 맞게 정의하기 위해 일반적으로 varchar(255)를 사용하기 보단 서비스에 맞게 정의된 글자수를 권장하고 있더라고요.
위에서 제가 답변한 부분에서 예찬님의 전체 스토리를 듣지 못하고 예찬님이 처음 varchar에 대해 언급해주신 답변을 봤을 때 고민의 흔적이 마지막에 적어주신 것만큼 보이지 않아 세게 강조하게 된 것 같습니다.(이 부분은 전달 방식을 좀 더 개선해볼게요 죄송합니당🙏)
말씀 감사합니다:)
저도 제 생각으로만 전달 드리다보니 합의점을 찾기가 어려웠던 것 같아요 그래서 테스트를 진행해보았습니다! (다음부턴 테스트해서 같이 합의점을 찾아보는 것도 좋을 것 같아요)
https://github.com/eco-dessert-platform/backend/issues/305 저희의 논점이었던 삽입, 조회 기준으로 작성했습니다
아침부터 계속 책읽고 작업하다보니 집중력이 많이 떨어져서 MySQL varchar(255)를 사용하는 이유 이거는 내일 읽고 판단해보겠습니다
감사합니다~
Issue: ✅ Feature
Description
API 엔드포인트
테이블 정보
복합키 선정 이유
기타 설명
To do
ETC
Explain
생성되는 쿼리문
인덱스를 잘 타고 있는 것을 확인
rank의 인덱스가 안걸려 있으면, 비효율적으로 인덱스를 탐
아직 자세한 내용 문의 중이라 계속해서 수정할 예정