1)
SELECT TOP 10000 ROW_NUMBER() OVER(ORDER BY A.BASE_DATE) AS ROW_NUM
A.DATA1
, A.DATA2
....
, A.DATE20
FROM DATA A
LEFT JOIN USER B
ON A.ID = B.ID
2)
SELECT TOP 10000 ROW_NUMBER() OVER(ORDER BY A.BASE_DATE) AS ROW_NUM
, A.DATA1
, A.DATA2
....
, A.DATA20
, B.USER_NAME
FROM DATA A
LEFT JOIN USER B
ON A.ID = B.ID
1번 과 2번의 차이는 2번 SELECT 에서 B.USER_NAME이라는 항목이 더 있을 뿐입니다.
두개테이블의 ID는 인덱스가 설정 되어 있습니다.
그런데 1번과 2번 쿼리의 속도가 10배정도 차이가 납니다. 1번 쿼리가 훨씬 빠릅니다.
SELECT 항목에 컬럼이 더 늘어난다고 속도가 차이가 발생하나요?
이런 경험을 해결 하신분 답변 부탁드립니다.
감사합니다.
Comment 7
-
minsouk
2014.12.30 23:03
-
mr-choi
2015.01.06 11:00
당연하다고 말씀 하신것이 데이터를 가져오는 양이 많아져서 늦어진다는 말씀인지요..
괜찮으시면 간단한 설명 부탁 드리겠습니다.
감사합니다.
-
바퀴벌레
2014.12.31 08:51
실행계획을 안본 상태에서 말씀을 드리기는 어렵구요.
별다른 where 조건은 없나요?DATA 쪽에 Seek된 Row가 많고 USER 와 loop join 이 되어서 생긴 문제 ( USER_NAME 값을 가지고 올 때 )라는 전제 아래
아직 초보인 저라면 일차적으로 다음과 같은 방법을 떠올릴 수 있을 것 같아요.
1) LEFT JOIN USER 을 hash 같은 힌트를 주어서 해보는 방법 (물론 USER 의 데이터 량과 사이즈가 크면 좀 힘드네요. )
2) USER 에서 가지고 오는 데이터가 USER_NAME 만 있다면, inner 쿼리로SELECT
.......
FROM DATA A
LEFT JOIN (SELECT ID, USER_NAME FROM USER ) AS B ON A.ID = B.ID바꾸어서 한번 해 보심은....
3) SELECT ID, USER_NAME FROM USER 이 부분을 임시테이블로 내려서 JOIN 을 해 보세요.
SELECT ID, USER_NAME INTO #USER FROM USER ;
SELECT
.....
, A.DATA20
, B.USER_NAME
FROM DATA A
LEFT JOIN #USER B -- 임시테이블 사용.
ON A.ID = B.ID;
4) USER 에 아예 인클루드 인덱스를 새로 만드세요.. ㅜㅜ
물론 USER_NAME 의 데이터가 크지 않다는 전제 입니다. ( 이름인데... 설마 크진 않겠지요?? )
굳히 정렬이 될 필요는 없으니까, include option 으로 USER_NAME 을 추가하는 것을 생각할 수도 있겠네요.
5) USER table 통계정보나, 테이블 단편화를 한점 점검해 보세여.JOIN 조건인 ID 값의 구조를 잘 몰라서 뭐라 말씀 드릴 수 없지만....
ID 가 순차적으로 발생하는 구조가 아니라면, 테이블 단편화 때문에 비슷한 경험을 한 적이 있습니다. -
mr-choi
2015.01.06 11:01
답변 감사드립니다.
다른 문제들 때문에 아직 테스트 해 보지 못했습니다.
답변 주신대로 테스트 해 보겠습니다.
-
맨즈밤
2014.12.31 09:04
2번의 경우 B.USER_NAME 에 의한 키룩업이 속도저하의 원인 아닐까요.
-
mr-choi
2015.01.06 11:02
답변 감사드립니다.
키룩업에 대한 속도저하라면 해결방법이 있나요?
-
솔봄
2015.01.06 13:30
Index 에 Include 시키세요
또는 covered Index로 Index에 출력하려는 모든 행을 넣는 방법도 있지요
물론 사이즈가 커지겠지만요
.