하위 쿼리를 사용하여 일치하는 필드가있는 모든 이전 레코드의 총 개수를 찾는 경우 성능이 50k 레코드만큼 적은 테이블에서 끔찍합니다. 하위 쿼리가 없으면 쿼리는 몇 밀리 초 안에 실행됩니다. 하위 쿼리를 사용하면 실행 시간이 1 분 이상입니다.
이 쿼리의 결과는 다음과 같아야합니다.
- 지정된 기간 내에 해당 레코드 만 포함하십시오.
- 날짜 범위에 관계없이 현재 레코드를 포함하지 않는 모든 이전 레코드 수를 포함합니다.
기본 테이블 스키마
Activity
======================
Id int Identifier
Address varchar(25)
ActionDate datetime2
Process varchar(50)
-- 7 other columns
데이터 예
Id Address ActionDate (Time part excluded for simplicity)
===========================
99 000 2017-05-30
98 111 2017-05-30
97 000 2017-05-29
96 000 2017-05-28
95 111 2017-05-19
94 222 2017-05-30
예상 결과
의 기간에 2017-05-29
대해2017-05-30
Id Address ActionDate PriorCount
=========================================
99 000 2017-05-30 2 (3 total, 2 prior to ActionDate)
98 111 2017-05-30 1 (2 total, 1 prior to ActionDate)
94 222 2017-05-30 0 (1 total, 0 prior to ActionDate)
97 000 2017-05-29 1 (3 total, 1 prior to ActionDate)
레코드 96 및 95는 결과에서 제외되지만 PriorCount
하위 쿼리에 포함됩니다.
현재 검색어
select
*.a
, ( select count(*)
from Activity
where
Activity.Address = a.Address
and Activity.ActionDate < a.ActionDate
) as PriorCount
from Activity a
where a.ActionDate between '2017-05-29' and '2017-05-30'
order by a.ActionDate desc
현재 색인
CREATE NONCLUSTERED INDEX [IDX_my_nme] ON [dbo].[Activity]
(
[ActionDate] ASC
)
INCLUDE ([Address]) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,
DROP_EXISTING = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
)
질문
- 이 쿼리의 성능을 향상시키기 위해 어떤 전략을 사용할 수 있습니까?
편집 1
DB에서 수정할 수있는 질문에 대한 답으로 : 테이블 구조가 아니라 인덱스를 수정할 수 있습니다.
편집 2
이제 Address
열에 기본 색인을 추가 했지만 그다지 향상되지는 않았습니다. 현재 임시 테이블을 만들고 값없이 값을 삽입 PriorCount
한 다음 각 행을 특정 카운트로 업데이트 하여 성능이 훨씬 뛰어납니다 .
편집 3
인덱스 스풀 Joe Obbish (허용 된 답변)에서 문제가 발견되었습니다. new를 추가 nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
하면 임시 테이블을 사용하지 않고 쿼리 시간이 1 분에서 1 초 미만으로 줄었습니다 (편집 2 참조).
nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
하면 쿼리 시간이 1 분에서 1 초 미만으로 줄어 들었습니다. 내가 할 수 있다면 +10 감사!