데이터베이스 개발자 질문과 답변 게시판
안녕하세요.
출석부를 출력하는데 시간이 너무 오래 걸려서 시간을 단축할 방법이 없을까 해서 문의 드립니다.
현재 서버와 DB가 따로 분리되어 있어서 더 느린것 같기도 한데....
고수님들의 좋은 방법 부탁 드리겠습니다.
저기 for 문 돌리면서 너무 느려지는듯.....
<%@LANGUAGE="VBSCRIPT" CODEPAGE="949"%>
<%StartTime=Timer() %>
<!-- #include virtual = "/include/Db.asp" -->
<%
dim ty,tm,td
ty=year(date())
tm="09"
td=day(date())
if len(tm)=1 then tm="0"+cstr(tm) end if
if len(td)=1 then td="0"+cstr(td) end if
dim yy,mm
If request("yy") = "" then
yy = ty
Else
yy = request("yy")
End If
If request("mm") = "" then
mm = tm
Else
mm = request("mm")
End if
''''''''''''''''''''''''''''''''''''''''''
begindate=yy&"-"&mm&"-01"
lastday=DatePart("d",DateAdd("d",-1,DateAdd("m",1,begindate)))
msday = begindate &" 06:00" '매달 첫날
meday = dateadd("m",1,begindate) &" 06:00" '매달 마지막날
Call dbopen()
SQL = "SELECT A.strID, strName, chk1 from Member A left outer join (select strID, COUNT((CASE WHEN strType =1 THEN 1 ELSE null END)) 'chk1' from TimeBook_2014 B where [strStime] between '"& msday &"' and '" & meday & "' group by B.strID) C on C.strID = A.strID where A.del ='0' order by A.strOrder "
'response.write sql
'멤버는 20명 쯤 됩니다.
SET RS = db.EXECUTE(SQL)
IF NOT(RS.EOF) Then
WHILE NOT(RS.EOF)
For i=1 to cint(lastday)
orderdate=trim(ty&"-"&tm&"-"&right("0"&cstr(i),2))
SQL = "SELECT [intNum], [strStime], [strType], [strMemo] FROM [TimeBook_2014] where strID = '" & RS("strID") & "' and [strStime] between '"& orderdate &"' and '" & dateadd("d",1,orderdate) & "' "
SET RS1 = db.EXECUTE(SQL)
IF NOT(RS1.EOF) Then
%>
<%=FORMATDATETIME(rs1("strStime"), 4)%>
<%=rs1("strType")%>
<%
End If
RS1.Close
Next
RS.MOVENEXT
WEND
End if
%>
<% Call dbclose() %>
<%response.write "실행시간 : "&FormatNumber(Timer()-StartTime,5)&" (초)" %>
Comment 3
-
처리짱
2014.10.01 19:10
-
항해자™
2014.10.01 21:40
디비와 웹서버는 분리되어 있는게 일반적으로 맞는 구조 입니다.
처리짱님의 의견대로 adhoc 쿼리를 프로시저로 변환하고,
루프문에서 실행될 쿼리 내용의 집합이 한번에 출력되도록 하는게 좋을 듯 합니다,,,
출석부라 하셨으니,,, 일자별로 출석한 사람의 이름을 출력하는 것이라면 쿼리가 크게 복잡하지 않을 것 같아 보이네요,,,
-
Hisory
2014.10.02 03:49
쿼리를 합치시는게 좋을듯 합니다...
while 문이 동작하는 속도보다는 쿼리를 합쳐 출력해내는것이 속도나 쿼리 이슈에서 좀더 좋지 않을까 싶네여
간단히 만들어본 내용은 아래 있습니다. 테스트는 안해봐서 에러는 있을수 있으니 참고 부탁드려여.
SELECT A.strID, strName, chk1 , D.[intNum], D.[strStime], D.[strType], D.[strMemo]
from
Member A
left outer join
(select strID, COUNT((CASE WHEN strType =1 THEN 1 ELSE null END)) 'chk1' from TimeBook_2014 B where [strStime] between '"& msday &"' and '" & meday & "' group by B.strID) C
on C.strID = A.strID
Outer Apply
(
SELECT [intNum], [strStime], [strType], [strMemo] FROM [TimeBook_2014] where strID = A.strID and [strStime] between '"& orderdate &"' and '" & dateadd("d",1,orderdate) & "' "
) AS d
where A.del ='0' order by A.strOrder
제 짧은 소견으로는
1. 쿼리를 프로시져로 바꿔서 호출함.
2. WHILE 안의 반복되는 쿼리를 한번에 데이터를 다 가져와서 처리함.
요정도 일까요..