안녕하세요
프로시져를 SSMS에서 실행하는거와 ERP 프로그램에서 실행하는거와
수행시간에 현저하게 차이가 나는데 PLAN이 변경되는거 같아요...
FROM 절에 뷰를 조인하는 부분이 있는데
그부분에서 PLAN이 바뀌는거 같네요...
동일한 프로시져를 수행하는건데 어떤 경우에 바뀌는지 설명부탁드립니다.
Comment 10
-
항해자™
2016.01.19 14:42
-
방자
2016.01.21 07:33
아래와 같은 프로시져를 호출하는데
SSMS에서는 정상 PLAN을 타는데
프로시저소스를 가지고 DECLARE 문이나 ERP 프로그램으로 수행시 변경된 플랜으로 타네요...
프로그램 호출 프로시져 : USP_TEST 'A','%','20160118','20160118','%','%','GA91102500%'
아래와 같은 SQL 유형이고 UV로시작하는건 VIEW입니다.
SELECT
생략
FROM I_GOODS_HDR I
JOIN I_GOODS_DTL A ( NOLOCK ) ON I.ITEM_DOCUMENT_NO = A.ITEM_DOCUMENT_NO
JOIN UV_B_ITEM ZB ON ZB.PLANT_CD = A.PLANT_CD AND ZB.ITEM_CD = A.ITEM_CD
-
항해자™
2016.01.21 13:56
가능하면 xml 파일로 부탁 드립니다,,,
위 이미지만 봐서는 쿼리 옵션으로 플랜을 고정할 수 있을 듯 한데, 자세히 보고 싶네요,,,
-
방자
2016.01.21 15:11
고정이 어떻게 가능한가요??
xml 파일 올려드립니다..
txt 확장자로 변환해서 올렸습니다.
-
항해자™
2016.01.22 01:57
올려주신 플랜이 프로그램에서 실행 당시의 것은 아닌 것 같습니다.
"변경후"의 플랜은 쿼리를 직접 실행한 것으로 보이네요.
쿼리 아랫 부분에 아래 구문을 삽입해서 실행해 보세요.
option(optimize for(@PLANT_CD='A', @SL_CD='%', @DOCUMENT_DT_F='20160118', @DOCUMENT_DT_T='20160118', @LOT_NO='%', @ITEM_CD='%', @BP_ITEM_CD='GA91102500%'))
-
항해자™
2016.01.22 02:04
느린 이유는 쿼리를 실행하기 위해 요청한 메모리가 실제 실행에 필요한 메모리 보다 적어서, table spool 이 많이 발생하게 되었기 때문인것 같습니다.
-
방자
2016.01.22 08:06
말씀하신 옵션을 사용하니 정상적으로 plan이 풀리네요...
실제 실행에 필요한 메모리 보다 적어서 그렇다는데
이 옵션을 주면 정상적으로 plan이 바뀌는 이유가 먼지요??
그리고 물리적인 메모리 공간이 부족하다는 말인가요???
-
항해자™
2016.01.22 17:04
물리 메모리가 부족은 아닐 수 있습니다.
쿼리를 실행하기 위해서는 여러가지 단계를 거치는데, 그 중에 옵티마이저의 비중이 상당합니다.
그 옵티마이저는 테이블 혹은 인덱스의 통계를 기반으로 플랜을 만드는데,
입력값을 가지고 그 값이 얼마나 있는지 예측하여 쿼리 메모리를 할당하게 됩니다.
그런데 실행 단계에서 파라미터를 바인딩하지 않거나, 로컬 변수를 사용하게 되면,
값이 unknown이 되므로 통계의 density를 이용하게 되어 정확도가 떨어지게 되는거죠.
위 쿼리 결과로 보아서는 이미 먼저 생성된 플랜에서 적절한 양의 메모리를 할당하였으나,
이 후에 실행하려는 쿼리에서 요구하는 메모리가 상대적으로 많아서, 메모리 부족한 현상을 일으킨 것 같아 보입니다.
-
항해자™
2016.01.22 17:07
optimize for를 이용하면 파라미터에 어떤 값이 들어 오던지 지정된 값으로 컴파일하라는 의미를 가집니다.
그러므로 지역 변수를 사용해도 항상 같은 플랜을 가질 수 있습니다.
주의할 점은 통계에서 값이 단계가 사라지게 되면 플랜에 영향을 미칠 수 있습니다.
그래서 항상 존재하는 값으로 지정해 주는 것이 좋습니다.
-
minsouk
2016.01.23 01:02
플랜은 안 봤지만 대충 올바른 길로 안내하네 더 깊은곳을 가봐야 할건데....
현재 상황과 변경전후 플랜 및 로직등을 올려 주시면 답변을 다는데 도움이 될듯 하네요,,,