티스토리 뷰

콘서트 예약시스템에서 사용하는 쿼리 중에서 인덱스로 성능을 개선할 수 있는 부분에 대해서 알아보자.

 

[콘서트 예약시스템에서 성능개선의 여지가 있는 쿼리]

 

특정일자에 대한 예약 가능한 좌석리스트 조회

@Query("SELECT s FROM Seat s WHERE s.seatNo = ?1 AND s.concert.concertId = ?2 AND s.concertSchedule.concertDate = ?3")
  public Seat findSeatBySeatNoAndConcert(Long seatNo, Long concertId, LocalDate concertDate);
 

위 쿼리를 보면 Seat 번호를 조회하기 위해서 Concert, ConcertSchedule 테이블과 조인을 한다.

만약에 좌석갯수가 3만석이라면 조회하는데 시간이 걸릴 것이다. 인덱스를 추가해서 성능 개선 예정.

 

성능 비교

1. 인덱스를 추가하기 전의 성능

@Table
public class Seat {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long seatId;

    @Column(name = "seat_no")
    private long seatNo;

    @ManyToOne
    @JoinColumn(name ="concert_id")
    private Concert concert;

    @ManyToOne
    @JoinColumn(name ="concert_schedule_id")
    private ConcertSchedule concertSchedule;
  }
 

- 좌석 갯수 10만개. 좌석번호 6110을 조회하는 쿼리

- 테스트 회차당 소요시간 : 1.074 / 1.058 / 1.148 / 1.144 / 1.057 / 1.087 / 1.135 / 1.053 / 1.117 / 0.992
- 10회 평균 1.0865초

 

2. 인덱스를 추가한 이후의 성능

@Table(name = "seat", indexes = @Index(name = "idx_seat2", columnList = "seat_no, concert_id"))
public class Seat {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long seatId;

    @Column(name = "seat_no")
    private long seatNo;

    @ManyToOne
    @JoinColumn(name ="concert_id")
    private Concert concert;

    @ManyToOne
    @JoinColumn(name ="concert_schedule_id")
    private ConcertSchedule concertSchedule;
  }
 

 

인덱스 선정 기준

Cardinality가 높은 컬럼 : seat_no(좌석번호) 컬럼은 좌석이 생길 때마다 채번되기 때문에 중복수치가 낮다.

- 좌석 갯수 10만개. 좌석번호 6110을 조회하는 쿼리

- 테스트 회차당 소요시간 : 0.816 / 0.833 / 0.817 / 0.825 / 0.800 / 0.786 / 0.678 / 0.736 / 0.741 / 0.799
- 평균 0.7831초

 

성능비교 결과

인덱스가 있을 때의 성능이 없을 때의 성능보다 27% 향상된 것을 확인할 수 있다.

댓글