안녕하세요. 오랜만에 인사드립니다.
다름이 아니라 뷰테이블 내에서 아래와 같이 group by를 썼는데 속도가 굉장히 느린 것 같습니다.
결과값은 수만개지만 웹에서 최종 쿼리는 페이징 쿼리를 따로 타서 20페이지씩 짤라서 보여주기는 하는데
이상하게 group by를 넣은 날부터 테스트 하시던 분들이 웹 조회가 굉장히 느려지고 MS-SQL을 사용하는
다른 어플리케이션들이 Timeout이 생긴다고 합니다.
DB쪽은 초짜라서 저렇게 group by를 써도 되는 것인지 모르겠습니다만 우선 결과가 잘 나오니 이렇게 쓰고는 있는데요
이걸 퍼포먼스를 고려하여 효과적으로 쿼리를 다시 짤 수 있을까요?
dbo.Pallet_Mst.PalletNo 항목을 기준으로 중복된 것이 많이 나와서 PalletNo 중복을 걸러서 묶어주려다 보니
저렇게 무식하게 많은 group by를 쓰게 되었습니다.
아니면 아예 처음부터 dbo.Pallet_Mst 테이블의 항목들을 중복 제거하여 조인을 걸어주는 방법을 쓰는 것이 나을런지요?
경험과 지식이 부족하여 이런 질문드리게 되어 죄송스럽게 생각합니다. 조언 주시면 정말 고맙겠습니다.
참고로 설치된 버전은 SQL 2012 입니다. 아래는 SQL Server가 느려지는 문제로 보이는 group by를 사용한
Vw_productPosition 테이블입니다.
위의 쿼리입니다.
SELECT dbo.Pallet_Mst.PalletNo, dbo.Product_Mst.PartNo, dbo.Pallet_Dtl.Qty, dbo.Product_Mst.ErpCode,
dbo.Product_Mst.PartNm, dbo.Product_Mst.Standard, dbo.Product_Mst.Unit, dbo.Product_Mst.ProcDiv,
dbo.Product_Mst.Data1, dbo.Product_Mst.Data2, dbo.Product_Mst.Data3, dbo.Product_Mst.Data4,
dbo.Pallet_Mst.PalletDiv, dbo.Code_Mst.DivCode, dbo.Code_Mst.DivNm, dbo.Code_Mst.CodeNm,
dbo.Pallet_Mst.PlantSite, Code_Mst_1.DivCode AS DivCode2, Code_Mst_1.CodeNo AS CodeNo2,
Code_Mst_1.DivNm AS DivNm2, Code_Mst_1.CodeNm AS CodeNm2, dbo.Pallet_Mst.PrintDate,
dbo.Pallet_Mst.PrintUser, dbo.Pallet_Mst.State, dbo.Pallet_Mst.RegDate, dbo.Pallet_Mst.RegTime,
dbo.Pallet_Mst.Note, dbo.Pallet_Mst.Loc, dbo.Pallet_Mst.AssFlag
FROM dbo.Pallet_Mst LEFT OUTER JOIN
dbo.Position_Info ON dbo.Pallet_Mst.Loc = dbo.Position_Info.Loc INNER JOIN
dbo.Pallet_Dtl ON dbo.Pallet_Mst.PalletNo = dbo.Pallet_Dtl.PalletNo INNER JOIN
dbo.Product_Mst ON dbo.Pallet_Dtl.PartNo = dbo.Product_Mst.PartNo INNER JOIN
dbo.Code_Mst ON dbo.Pallet_Mst.PalletDiv = dbo.Code_Mst.CodeNo INNER JOIN
dbo.Code_Mst AS Code_Mst_1 ON dbo.Pallet_Mst.PlantSite = Code_Mst_1.CodeNo
WHERE (dbo.Code_Mst.DivCode = '01') AND (Code_Mst_1.DivCode = '10') AND (dbo.Pallet_Mst.State = 'W')
GROUP BY dbo.Pallet_Mst.PalletNo, dbo.Product_Mst.PartNo, dbo.Pallet_Dtl.Qty, dbo.Product_Mst.ErpCode,
dbo.Product_Mst.PartNm, dbo.Product_Mst.Standard, dbo.Product_Mst.Unit, dbo.Product_Mst.ProcDiv,
dbo.Product_Mst.Data1, dbo.Product_Mst.Data2, dbo.Product_Mst.Data3, dbo.Product_Mst.Data4,
dbo.Pallet_Mst.PalletDiv, dbo.Code_Mst.DivCode, dbo.Code_Mst.DivNm, dbo.Code_Mst.CodeNm,
dbo.Pallet_Mst.PlantSite, Code_Mst_1.DivCode, Code_Mst_1.CodeNo, Code_Mst_1.DivNm,
Code_Mst_1.CodeNm, dbo.Pallet_Mst.PrintDate, dbo.Pallet_Mst.PrintUser, dbo.Pallet_Mst.State,
dbo.Pallet_Mst.RegDate, dbo.Pallet_Mst.RegTime, dbo.Pallet_Mst.Note, dbo.Pallet_Mst.Loc, dbo.Pallet_Mst.AssFlag
어떻게 다듬어야 퍼포먼스가 나올까요? 고수분들의 도움이 절실합니다.
Comment 3
-
건우아빠
2013.09.12 11:46
-
항해자™
2013.09.12 13:27
그룹 바이가 많아서 라기보다 조인이 많아서 느릴 것 같네요,,
인덱스를 잘 타고 있는지 봐야 하겠구요,,
집계 함수를 사용하지 않으면 그룹바이 대신 distinct를 이용하면 조금 더 빠를 수 있습니다,,, -
여우비™
2013.09.12 18:35
공통적으로 사용하는 View라고 한다면, View를 사용하는 전체 Query Block에서 View의 조건을 줄여줄 수 있는 조건절이 있어야만 성능을 발휘할 수 있습니다.(물론 조건에 맞는 index 정책도 필요합니다.)
하여 해당 View내용만으로는 '어떤 부분이 문제다.' 라고 확인하기 어렵네요.
View는 공통적인 모듈로 만드는 것보다는 기능에 맞는 최소한의 범위내에서 모듈화 하는 것이 성능관리 측면에서 좋습니다.
Pallet_Mst LEFT OUTER JOIN dbo.Position_Info
Position_Info의 정보를 가져오는 부분이 없는데 굳이 left 조인을 거실 필요가 있나요?
코드의 이름을 가져오는 부분은 group by 결과와 나중에 조인으로 처리하셔도 .....