쿼리문 개선좀 도와주세요
본문
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
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
위 쿼리는 하위 쿼리를 사용하여 g5_order 테이블에서 is_payed가 'Y'인 주문의 수를 계산한 다음, 이를 discount_event 테이블과 조인하여 필요한 데이터를 추출합니다. 이 방법은 부분적으로 성능을 향상시킬 수 있으며, 실행 계획에 따라서는 전체적인 성능 개선이 가능할 수 있습니다.
그러나 이 쿼리가 완전히 최적화된 것은 아니므로, 더 좋은 성능을 위해서는 인덱스 등을 사용하여 쿼리를 재구성해야 할 수도 있습니다. 또한, 데이터베이스에서 쿼리를 실행할 때 발생하는 다양한 성능 이슈를 고려하여 최적화하는 것이 중요합니다.
from ChatGPT
!-->1. 데이터 개수가 많아지면 답이 없습니다.
카운트를 위한 별도 테이블을 생성후
order테이블 등록 시점에 키와 매칭하는 등록 개수를 업데이트 하도록 하고
조인 + 페이징 으로 쿼리하는 방법이 효율적입니다.
2. 관리 측면에서만 봐야 하고 조회시간의 지연이 크게 상관없는 경우
복제용 slave 를 생성하고 그쪽에서 조회 해보는 방법이 있습니다.
이 경우 시간이 지체되더라도 서비스에는 영향이 없습니다.
g5_order 에서
de.de_idx 값이 어떻게 들어 가나요?
g5_order에서 update, insert할 때마다
discount_event.de.limited_count를 갱신 해 주는 것도 방법입니다.