2012-10-19 3 views
0

ASP.NET MVC3 응용 프로그램과 함께 작업하고 있으며 시작일과 종료일 및 작업 일을 나열하는 버스 여행에 대한 데이터베이스 테이블이 있습니다.쿼리 구체화 삽입 - SQL Server

2012년 1월 2일의 날짜가 월요일, 월요일이 true로 설정되어이 경우
JourneyID StartDate EndDate  Monday Tuesday Wednesday etc 
676   02 Jan 2012 01 Mar 2012 True False True  etc 
696   02 Jan 2012 01 Mar 2012 False False True  etc 
650   02 Jan 2012 25 Mar 2012 True True True  etc 

는, 그 일에 여행이 : 여기에 아래의 코드 조각입니다. 그것이 될 것입니다, 그래서

나는 그들이 실행 매일 새로운 테이블 행에 다음을 삽입하기 위해 노력하고있어 :

JourneyID Date 
676   02 Jan 2012 
676   04 Jan 2012 
696   04 Jan 2012 
650   02 Jan 2012 
650   03 Jan 2012 

시스템에 현재이 작업을 수행하는 쿼리가 매우 느리다 - t-sql에서 중첩 된 while 루프를 사용합니다. C#에도 버전이 있었지만 유사한 프로세스 (중첩 된 루프 프로세스를 사용한 다음 저장된 목록을 일반 목록에 삽입 한 다음 일괄 삽입)를 사용했지만 약간 느린 버전이었습니다

사용중인 모든 여행은 현재 모든 여행을 반복하며 각 여행 내내 시작일과 종료일 사이의 모든 날짜를 반복하여 어느 날에 해당하는지 그리고 그 날을 true로 설정했는지 확인합니다. 수행하는 데 오랜 시간이 걸릴 수 있습니다.

누구나이 삽입을 수행하는보다 효율적인 방법을 생각해 낼 수 있습니까? 현재 약 1 시간에 약 10 만 건의 여행을 반복 할 수 있지만 잠재적으로 수백만 건의 여행이있을 수 있으므로 오랜 시간이 걸릴 수 있습니다.

답변

1

효과적으로 반전 해제 한 다음 필터링합니다.

;with cte as 
(
    select JourneyID, StartDate,EndDate,Days 
    from yourtable s unpivot (active for days in (Monday, tuesday, wednesday, ...)) u 
    where active = 1 
) 
    select JourneyID, JourneyDate 
    from (
     select 
      DATEADD(D, number, (Select MIN(startdate) from cte)) as JourneyDate 
     from master..spt_values 
     where type='p' 
     and number < (select datediff(d,MIN(StartDate),max(enddate)) from cte) 
    ) numbers 
     cross join cte 
    where 
     days = datename(weekday, JourneyDate) 
     and JourneyDatebetween StartDate and EndDate 
    order by JourneyDate, JourneyID 
+0

안녕하세요, podiluska, 나는이 질문을 한 직후이 프로젝트에서 벗어나게되었습니다. 방금 돌아와서 대답을 시도해 보았습니다. 정말 잘 돌아갑니다. 정확히 내가 뭘 찾고 있었는지, 고마워. :) –

0

캘린더 테이블을 만들고 가입하십시오. 요일은 테이블 설정 (부당 월요일, 화요일 등)의 약간 까다로운 원인입니다. 투어가 어린이 테이블로 실행되는 날을 표준화하고 추출하는 것이 훨씬 쉬울 것입니다.

INSERT INTO NewTable (Journey, Date) 
SELECT J.JourneyId, C.Date FROM Journey J 
INNER JOIN JourneyWeekdays JW ON J.Id = JW.JourneyId 
INNER JOIN Calendar C ON (C.Date BETWEEN JT.StartDate AND JT.EndDate) AND C.DayOfWeek = JW.DayOfWeek 

이 좋은 성능이해야 적절한 색인을 사용하여 다음과 같은 설정으로

이 같은 쿼리를 작성할 수 있습니다.