지난 1 일, 지난 7 일, 지난 30 일 및 ID 당 모든 시간에 대한 결과를 요약하는 쿼리가 있습니다. 내가 가진 쿼리는 작동하지만 예상했던 것보다 느립니다.
이것은 내가 실행중인 쿼리입니다.
SELECT
v.id,
v.dtt,
v.date_hours as day_date_hours,
w.date_hours as week_date_hours,
m.date_hours as month_date_hours,
t.date_hours as total_date_hours
FROM example v
LEFT JOIN (SELECT id, sum(date_hours) as date_hours from example WHERE dtt > sysdate-7 group by id) w
ON w.id = v.id
LEFT JOIN (SELECT id, sum(date_hours) as date_hours from example WHERE dtt > sysdate-30 group by id) m
ON m.id = v.id
LEFT JOIN (SELECT id, sum(date_hours) as date_hours from example group by id) t
ON t.id = v.id
WHERE
dtt = '20-AUG-2014'
GROUP BY v.id, v.dtt, v.date_hours, w.date_hours, m.date_hours, t.date_hours
order by v.id
출력 요약입니다.
+-----+--------------------------------+-----------------+------------------+-------------------+------------------+
| ID | DTT | DAY_DATE_HOURS | WEEK_DATE_HOURS | MONTH_DATE_HOURS | TOTAL_DATE_HOURS |
+-----+--------------------------------+-----------------+------------------+-------------------+------------------+
| 1 | August, 20 2014 00:00:00+0000 | 18.5 | 111.65 | 415.25 | 444.75 |
| 2 | August, 20 2014 00:00:00+0000 | 10.5 | 116.65 | 451.55 | 475.05 |
+-----+--------------------------------+-----------------+------------------+-------------------+------------------+
질문에 대한이 샘플과 달리 몇 가지 참고 사항 example
은 실제로 표 입니다. 나는보기를 통제하지 않는다. 내가 제공 한보기이지만 example
테이블 과 똑같 습니다. 다음과 같은 정의가 있습니다.
CREATE TABLE example (
id varchar(15),
dtt DATE,
date_hours NUMBER
);
보기에는 약 1000 개의 고유 ID에 걸쳐 약 20 만 개의 레코드가 포함됩니다. 내 쿼리를 실행하는 데 약 8 분이 걸립니다.
내 문제는 내 JOIN에서 3 개의 하위 쿼리를 수행하고 있다는 것입니다. 이러한 직감에도 불구하고 이러한 요약 통계를 수집하는 더 효율적인 방법이 있는지 (또는 있는지) 잘 모르겠습니다. 8 분 실행 시간에 전체 테이블을 선택하고 애플리케이션의 모든 계산을 더 빠르게 수행 할 수있었습니다. 차라리 이것을하지 않을 것입니다.
이 SQLFiddle 에서 내 테이블 및 쿼리의 샘플 세트에 대한 링크를 사용할 수 있습니다.
쿼리를 더 효율적으로 만들면서 동일한 결과 집합을 유지하려면 어떻게해야합니까?
조건부 집계를 사용하여 요약을 한 번만 수행하십시오.
SELECT v.id, v.dtt, v.date_hours as day_date_hours,
h.week_date_hours, h.month_date_hours, h.total_date_hours
FROM example v LEFT JOIN
(SELECT id,
sum(case when dtt > sysdate-7 then date_hours end) as week_date_hours,
sum(case when dtt > sysdate-30 then date_hours end) as month_date_hours,
sum(date_hours) as total_date_hours
from example
group by id
) h
ON h.id = v.id
WHERE dtt = DATE '2014-08-20'
order by v.id ;
나는 겉옷 group by
이 필요 하다고 생각하지 않습니다 . 그렇다면 select distinct
.
편집하다:
또한 분석 함수를 사용하여 이것을 작성할 수 있다고 생각합니다.
SELECT v.*
FROM (SELECT v.id, v.dtt, v.date_hours as day_date_hours,
sum(case when dtt > sysdate-7 then date_hours end) over (partition by v.id) as week_date_hours,
sum(case when dtt > sysdate-30 then date_hours end) over (partition by v.id) as month_date_hours,
sum(date_hours) over (partition by v.id) as total_date_hours
FROM example v
) v
WHERE dtt = DATE '2014-08-20'
order by v.id ;
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다