-
Notifications
You must be signed in to change notification settings - Fork 1
refactor : 보조인덱스 삽입속도 vs 복합키 random IO #11
Copy link
Copy link
Closed
Description
보조인덱스 삽입속도 vs 복합키 random IO
좋아요 개수와, member가 좋아요 했는지 여부를 확인하는 쿼리이다.
SELECT pl.post_id,
COUNT(*) AS like_count,
MAX(CASE WHEN pl.member_id = ? THEN TRUE ELSE FALSE END) AS amILiking
FROM post_likes pl
WHERE pl.post_id IN (?, ?, ?, ...)
AND pl.deleted_at IS NULL
GROUP BY pl.post_id위 쿼리를 수행하는데 가장 최적화 된 테이블 구조를 작성하려고 한다.
추가로 데이터 삽입 시의 성능까지 함께 고려해야한다.
- 복합키 전략.
@Table(name = "post_like"
public class PostLike {
@EmbeddedId
private PostLikeId id;
@Column(name = "deleted_at")
protected LocalDateTime deletedAt;
}
public class PostLikeId implements Serializable {
@Column(name = "post_id")
private String postId;
@Column(name = "member_id")
private Long memberId;
}-
단일 키 + 보조인덱스 전략.
@Table( name = "post_likes", indexes = { @Index(name = "idx_post_likes_post_id", columnList = "postId", "memberId", "deleted_at") } ) public class PostLike { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "post_id") private String postId; @Column(name = "member_id") private Long memberId; @Column(name = "deleted_at") protected LocalDateTime deletedAt; }
조회 쿼리비교 :
- 복합키 :
- 조회 시 버퍼풀 올리고, 클러스터드 인덱스의 postId와 memberId를 검색하여 찾아낸다.
- 좋아요 개수와 내가 좋아요 했는지 여부는 빠르게 인덱스로 찾아낼 수 있고, 그 내부에서 raw 데이터인 삭제여부를 체킹해야한다. (그래봐야 10번 조금 넘게 비교 수행, 무시가능)
- 단일키 + 커버링인덱스
- 쿼리에 포함된 조건이 모두 포함된 커버링인덱스 이므로, 보조인덱스만 버퍼풀에 올려서 작업을 마칠 수 있다.
- 삭제여부도 인덱스에 포함되어있으므로 바로 구분할 수 있다.
조회 쿼리의 경우, 비슷한 속도로 나올 것으로 추정된다.
그렇다면 삽입 시엔 어떻게 될까.
삽입 쿼리비교 :
- 복합키 :
- 현재 postId 가 문자열이기 때문에, 랜덤 IO 가 크게 발생할 수 있다.
- mongoDB _id의 시작 8자는 16진수 time stamp 값이다.
- 고로 binary 값으로 변환하여 저장한다면, 랜덤 io를 조금 줄일 수는 있을 것이다.
- 단일 키 + 커버링인덱스 :
- 삽입, 수정마다 보조인덱스까지 함께 수정해야하기 때문에 오래 걸린다.
- 저장된 데이터의 양이 두배가 넘게 뛰는 문제가 있다.
-
데이터 계산
- 클러스터드 인덱스 (66B)
- id : 8B
- postId : 12B
- memberId : 8B
- deletedAt : 8B
- 기본 구성요소 : 20B~
- 보조인덱스 (56B)
- postId… deleted_at + id == 46
- 기본 구성요소 : 10B~
100만 mau 이므로 한명당 좋아요 1000회 가정 → 1억건
56억 B → 5.6기가 정도.
디스크 입장에선 그리 큰 양은 아닌 것 같다.
버퍼풀에도 보조인덱스만 올릴 것이니, 오히려 이득이거나 비슷할 것으로 추정된다.
- 클러스터드 인덱스 (66B)
-
데이터의 양이 더욱 많아질 수록, random IO가 심해질 것이므로, 상대적으로 튜플의 크기는 작고, 개수가 많은 좋아요의 경우 랜덤 IO 를 방지하는 단일키 방식을 사용하겠다.
복합키 케이스에 비해서는 미약한 성능이나, 보조인덱스 삽입시에서도 랜덤 io가 발생할 수 있으므로, postId를 바이너리로 치환 후 저장하겠다.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels