공부/인프런 - Rookiss

Part 5-3-10. SQL 튜닝 : Sorting

셩잇님 2024. 7. 18. 11:50
반응형

 

 

🌞 SQL 튜닝

 

 지난 시간에는 조인의 3가지 마지막 원리로 Hash 조인에 대해서 알아보았다. 해시 조인은 인덱스의 유무에 영향을 받지 않고, 정렬이 필요하지 않다는 장점을 가지고 있다. 오늘은 Sorting 즉 정렬에 대해서 알아보는 시간을 가져보도록 하자.

 

 이번 시간에는 Northwind 데이터베이스를 사용하는 것이 아닌, 다시 BaseballData  데이터베이스를 사용한다.

 



🎑 Sorting

 

 알게 모르게 많이 사용했지만, 사실 정렬은 굉장히 위험한 놈이다. 일반적으로 클라이언트에서 사용하는 데이터는 크기가 그렇게 크지도 않고, 일반적인 정렬의 시간복잡도는 O(NlogN)이기 때문에 한 두번 하는건 그렇게 위험하지 않다. 그러나 DB에서 사용하는건 유의해야 한다.

 

DB는 클라이언트와 다르게 데이터의 크기가 어마어마하게 크기 때문에 사용에 유의해야 한다. 만약 클라이언트에서 사용하는 것처럼 Sorting을 무지성으로 사용 할 경우 데이터 용량이 매우 크기 때문에 사용자가 사용할 수 있는 가용 메모리로 커버가 안되는 상황이 온다. 이럴 경우 메모리 부족으로 인해 HDD, SDD에 접근하게 되는데 메모리 접근과 하드 디스크의 접근 속도의 차이는 몇 십배이상 차이나기 때문에 유의해야한다.

 

 따라서 우리는 Sorting이 언제 일어나는지 파악하고 있어야 한다.

 

-- Sorting이 일어날 때
-- 1) SORT MERGE JOIN
	-- 원인) 알고리즘 특성 상 MERGE 하기 전에 SORT를 해야 함
    
-- 2) ORDER BY
-- 3) GROUP BY
-- 4) DISTINCT
-- 5) UNION
-- 6) RANKING WINDOWS FUNCTION
-- 7) MIN, MAX
	-- 원인) 테스트 하면서 알아보도록 하자

 

 총 7가지의 경우에서 Sorting이 일어나는데, 1번은 이전에 배웠기 때문에 생략하고 2번부터 6번까지 테스트하면서 소팅이 언제 일어나는지 확인하도록 하자.

 


 

-- 2) ORDER BY
-- 테이블 조회
SELECT *
FROM players
ORDER BY college;
-- 원인) ORDER BY 순서로 정렬을 해야하기 때문에 SORT를 한다.

 

 소팅이 일어나는 원인은 단순하다. ORDER BY 순서로 정렬을 해야하기 때문에 소팅이 일어난다.

 

-- 3) GROUP BY
SELECT college, COUNT(college)
FROM players
WHERE college LIKE 'C%'
GROUP BY college;
-- 원인) 집계를 하기 위해 SORT를 한다.

 

 마찬가지로 소팅이 일어나는 원인은 ORDER BY 순서로 정렬을 해야하기 때문에 소팅이 일어난다.

 

-- 4) DISTINCT
SELECT DISTINCT college
FROM players
WHERE college LIKE 'C%';
-- 원인) 중복을 제거하기 위해 SORT를 한다

-- 5) UNION
SELECT college
FROM players
WHERE college LIKE 'B%'
UNION
SELECT college
FROM players
WHERE college LIKE 'C%';
-- 원인) 중복을 제거하기 위해 SORT를 한다.

 

DISTINCT, UNION 모두 소팅이 일어나는 이유는 중복을 제거하기 위해 소팅이 발생한다.

 

-- 6) 순위 윈도우 함수
SELECT ROW_NUMBER() OVER (ORDER BY college)
FROM players;
-- 원인) 집계를 하기 위해 SORT를 한다.

 

 순위 윈도우 함수 또한 집계를 하기 위해 소팅하는 것을 알 수 있다.

 


 

 그렇다면 소팅을 줄이는 방법은 무엇이 있을까? 바로 Index를 활용하는 것이다. 인덱스를 활용하면 소팅은 굳이 하지 않게된다. ORDER BY와 GROUP BY를 각각의 테이블에서 인덱스를 확인해 이를 통해 조회해보자.

 

-- INDEX를 활용한 ORDER BY
SELECT *
FROM batting
ORDER BY playerID, yearID;
-- batting 테이블의 index를 활용할 경우 Sorting이 사라지는 것을 볼 수 있다.

-- INDEX를 활용한 GROUP BY
SELECT playerID, COUNT(playerID)
FROM players
WHERE playerID LIKE 'C%'
GROUP BY playerID;
-- 마찬가지로 index를 활용했기 때문에 Sorting이 사라진 것을 볼 수 있다.

 

 두 개의 쿼리 실행계획에서 소팅이 모두 사라진 것을 볼 수 있다. 단, 4, 5번 같은 경우 2,3번과 결이 다르고 케이스 바이 케이스가 심하기 때문에 사용하기 전에 해당 키워드가 '정말 필요한가?'를 다시 생각해보고 사용하는 수 밖에 없다.

 


 

🎑 결론

 

 Sorting(정렬)을 줄이자. 정렬은 사실 위험한 놈이다. 클라이언트에서 한 두번 사용하는건 그렇게 위험하지 않다. 단, DB는 데이터가 어마어마하게 많기 때문에 유의해야 한다. 이 때 용량이 너무 커 가용 메모리로 커버가 안될 경우 메모리 부족으로 인해 디스크까지 찾아가게 되는데 메모리 접근과 디스크 접근의 속도 차이는 몇 십배이상 나기 떄문에 사용에 유의해야 한다.

 

 

반응형