테스트 사이트 - 개발 중인 베타 버전입니다

쿼리문 개선좀 도와주세요 채택완료

라균 2년 전 조회 1,952

select * from discount_event de

where de.limited_count > 0 and state = 'available'

  and de.limited_count <= (select count(*) from g5_order o where de.de_idx = o.de_idx and o.is_payed='Y')

 

mysql 을 사용중입니다.

이번에 이벤트 할인을 개발하며 선착순 기능이 들어가 있어서 order테이블에서 몇개를 사용했는지 보고있습니다.

문제는 g5_order 의 갯수가 4만5천건이 넘어가며 쿼리 조회 대기시간동안 서버가 너무 느려지는 현상이 발생합니다 ㅠㅠ

저 쿼리문을 어떻게 해야 개선할수있을까요?

댓글을 작성하려면 로그인이 필요합니다.

답변 3개

채택된 답변
+20 포인트
따삼이
2년 전

이 쿼리는 부분적으로 최적화될 수 있습니다. 우선, 하위 쿼리에서 count(*) 함수를 사용하는 것은 성능에 부담을 줄 수 있으므로, 조인을 사용하여 성능을 향상시킬 수 있습니다. 다음은 개선된 쿼리입니다.

</p>

<p>SELECT de.*

FROM discount_event de

JOIN (

  SELECT de_idx, COUNT(*) AS order_count

  FROM g5_order

  WHERE is_payed = 'Y'

  GROUP BY de_idx

) o ON de.de_idx = o.de_idx

WHERE de.limited_count > 0

  AND de.state = 'available'

  AND de.limited_count <= o.order_count</p>

<p>

 

위 쿼리는 하위 쿼리를 사용하여 g5_order 테이블에서 is_payed가 'Y'인 주문의 수를 계산한 다음, 이를 discount_event 테이블과 조인하여 필요한 데이터를 추출합니다. 이 방법은 부분적으로 성능을 향상시킬 수 있으며, 실행 계획에 따라서는 전체적인 성능 개선이 가능할 수 있습니다.

 

그러나 이 쿼리가 완전히 최적화된 것은 아니므로, 더 좋은 성능을 위해서는 인덱스 등을 사용하여 쿼리를 재구성해야 할 수도 있습니다. 또한, 데이터베이스에서 쿼리를 실행할 때 발생하는 다양한 성능 이슈를 고려하여 최적화하는 것이 중요합니다.

 

from ChatGPT

로그인 후 평가할 수 있습니다

댓글을 작성하려면 로그인이 필요합니다.

g5_order 에서

 de.de_idx 값이 어떻게  들어 가나요?

g5_order에서 update, insert할 때마다

discount_event.de.limited_count를 갱신 해 주는 것도 방법입니다.

로그인 후 평가할 수 있습니다

댓글을 작성하려면 로그인이 필요합니다.

2년 전

1. 데이터 개수가 많아지면 답이 없습니다.

카운트를 위한 별도 테이블을 생성후

order테이블 등록 시점에 키와 매칭하는 등록 개수를 업데이트 하도록 하고

조인 + 페이징 으로 쿼리하는 방법이 효율적입니다.

 

2. 관리 측면에서만 봐야 하고 조회시간의 지연이 크게 상관없는 경우

복제용 slave 를 생성하고 그쪽에서 조회 해보는 방법이 있습니다.

이 경우 시간이 지체되더라도 서비스에는 영향이 없습니다.

로그인 후 평가할 수 있습니다

댓글을 작성하려면 로그인이 필요합니다.

답변을 작성하려면 로그인이 필요합니다.

로그인