우선 별도의 step 을 두어서, 원하는 occ_time 에 해당하는 occ_time 의 최대 최소값을 구한 후,
해당 최대, 최소의 occ_time 에 해당하는 PK index key 인 logid 를 조회하도록 했습니다.
3초면 해결될 부분을 Nested loop 를 돌면서 MS-SQL 의 timeout 이 발생하도록 되어 있었습니다.
업무 프로세스 상으로,
logid 가 특정시간 (ex. 2008-05-25 06:00:00 이러한 시간 ) 에 있을 수도 있고,
없을 수도 있는 문제 때문에, 정확한 logid 를 얻는게 불분명했던 문제입니다.
중복이 있는 컬럼의 index key 에서도, MAX, MIN 값만 구하는건 잘 되네요.
쿼리를 합치면 문제지만...
어쨌든, 꼼수로 해결은 했습니다.
--------------------------------------------------------------------------------------------------------------------------------------
서브쿼리에서 찾아올 때는 풀 스캔, 키 값의 범위를 주면 index 를 타는 문제
< index key 값은 다음과 같습니다. >
IX_logTable_occ_time nonclustered located on PRIMARY occ_time <<< 중복이 있는 index key
UPK_logTable clustered, unique, primary key located on PRIMARY logid <<< 중복이 없는 index key
1. 프로그램에서 STEP1 과 STEP2 를 구한 후, STEP3 의 logid 에 입력하여, 3번 쿼리를 실행하면 3초면 됩니다.
-- STEP 1)
select min(logid) from logTable where occ_time = (
select min(occ_time) from logTable
where occ_time >='2008-05-25 06:00:00' and occ_time<='2008-05-26 06:00:00')
-- 10114701
-- STEP 2)
select max(logid) from logTable where occ_time = (
select max(occ_time) from logTable
where occ_time >='2008-05-25 06:00:00' and occ_time<='2008-05-26 06:00:00')
-- 10860997
-- STEP 3)
select eq.LocationCode, sl.sysloglevel,
max(a.occ_time) occ_time, count(a.LocationCode) OccuredCNT
from dbo.logTable a
inner join eqTable eq on a.locValue=eq.locValue
inner join levelTable sl on a.levelVar=sl.levelVar
where sl.levelVar !='8'
and
a.logid >= 10114701 <<<<<<<<<<<<<<<<<<<<<<<<<<<< 이 값을 구하는 서브 쿼리를 넣을 경우, 풀 스캔
and
a.logid <= 10860997 <<<<<<<<<<<<<<<<<<<<<<<<<<<<
group by eq.locValue, sl.levelVar
< 이렇게 조회하면, 약 3초 이하 >
2. 다음과 같이 logid 값을 step1, step2 의 서브쿼리를 넣어서 조회하면, 풀 스캔이 납니다.
select eq.locValue, sl.levelVar,
max(a.occ_time) occ_time, count(a.locValue) OccuredCNT
from dbo.logTable a
inner join eqTable eq on a.locValue=eq.locValue
inner join levelTable sl on a.levelVar=sl.levelVar
where sl.levelVar !='8'
and
a.logid >= select min(logid) from logTable where occ_time = (
select min(occ_time) from logTable
where occ_time >='2008-05-25 06:00:00' and occ_time<='2008-05-26 06:00:00')
and
a.logid <= select max(logid) from logTable where occ_time = (
select max(occ_time) from logTable
where occ_time >='2008-05-25 06:00:00' and occ_time<='2008-05-26 06:00:00')
group by eq.locValue, sl.levelVar
< 이렇게 조회하면, 약 20초 이상 >
잘 모르겠네요.
예상 실행 계획을 보면,
a.logid >= select min(logid) from logTable where occ_time = (
select min(occ_time) from logTable
where occ_time >='2008-05-25 06:00:00' and occ_time<='2008-05-26 06:00:00')
이 곳에서 Nested Loops / inner join 이 생긴다는데,
알 수가 없네요.
답변 부탁드립니다.