SELECT
DISTINCT to_char(created_ymd, 'YYYY-MM-DD') AS ymd, space_id
FROM history
WHERE created_ymd >= '시작날짜'::date - INTERVAL '3 months'
AND created_ymd <= '종료날짜'::date
history 테이블에서 pk는 id입니다.
| id | integer | PK |
| created_ymd | timestamp | not null |
| price | integer | not null |
| space_id | integer | not null |
...
...
시작날짜부터 종료날짜까지 기준날짜별로 3개월 전부터 해당 기준날짜까지의 space_id와 기준날짜를 구해야합니다.
space_id는 중복값이 있어서 중복값을 제거하려고 DISTINCT를 사용했고 날짜 형식 변경이 필요해서 to_char()를 활용했습니다.
ex)
| id | created_ymd | price | space_id |
| 1001 | 2022-09-26 05:11:39.632096+00 | 10000 | 12567 |
| 2019 | 2022-11-21 05:11:39.632096+00 | 20000 | 12567 |
| 3003 | 2022-12-13 05:12:32.767721+00 | 30000 | 12567 |
시작날짜가 만약 2022-12-15라면
3개월 전부터 2022-12-15까지에 포함되는 애들을 찾아야하고
위 테이블 예시에서 3개가 전부 해당되고 12567로 space_id가 같으므로 결과가
| 12567 | 2022-12-15 |
위와 같이 산출되면 좋겠습니다.
작성한 쿼리로 돌리면 결과가 나오긴 하지만 조회 속도가 많이 걸려서 성능을 개선하고 싶어 도움 요청드립니다ㅠㅠㅠㅠ
6일치 데이터 양은 평균적으로 천칠백만건 정도 됩니다.
+ 추가
인덱스에 "idx_created_ymd" btree (created_ymd), "idx_space_id" btree (space_id)가 있습니다.
원하는 결과는 space_id 인 듯 한데요?
조회 쿼리는 created_ymd 와 place_id 를 조회하네요? 왜죠?
created_at 은 created_ymd 와 다른 컬럼인가요?
place_id 는 space_id 와 다른 컬럼인가요?
조건의 시작일자와 종료일자는 다른 값인가요?
각 컬럼들의 정보를 정확하게 주셔야 할 것 같습니다.
space_id 는 총 몇건정도 되나요? space_id 를 pk 로 하는 별도 테이블은 없나요?
테이블은 파티션되어 있나요?
컬럼명은 제가 잘못 입력했네요.... 수정해 두겠습니다.
시작일자와 종료일자는 다른 값입니다.(created_ymd는 공간을 이용한 일자입니다.)
시작일자 - 3개월부터 종료일자 사이에 공간을 한번이라도 이용한 공간을 구하기 위함입니다.
space_id를 pf로하는 space테이블이 있습니다.
테이블 정보를 보면 Check constraints이 있는데 이게 파티션 되어 있다는 의미일까요...?
6일치 데이터 양은 평균적으로 천칠백만건 정도 됩니다.
1. Select 절에서 created_ymd 가 필요 없지 않나요?
- 변경전 : SELECT DISTINCT to_char(created_ymd, 'YYYY-MM-DD') AS ymd, space_id
- 변경후 : SELECT DISTINCT space_id
2. 스페이스의 건수는요?
3. 종료일은 어떤 값인가요?
- 시작일 : 2022-12-15
- 종료일 : ? 기간이(일주일? 한달?, 하루?, 1년?)
4. 파티션 테이블 여부?
5. 결합 인덱스는 없나요?
2. history테이블의 전체 건수는 324887388 / space테이블의 전체 건수는 29628입니다.
3. 종료일은 현재 날짜 또는 과거 날짜로 제한이 있지는 않습니다.
4. 없는 것 같습니다.
5. 넵. 결합된 인덱스는 없습니다.
1. 결합인덱스를 만들 수 있나요?
- 만약 (space_id, created_ymd) 형태의 결합인덱스가 있다면?
- space 테이블을 이용하여 빠른 조회가 가능할 것으로 예상됩니다.
SELECT space_id
FROM space s
WHERE EXISTS (SELECT 1
FROM history
WHERE space_id = s.space_id
AND created_ymd <= '종료날짜'::date
HAVING MAX(created_ymd) >= '시작날짜'::date - INTERVAL '3 months'
)
;