데이터베이스 정렬 vs Java 정렬
728x90
반응형

 

가끔 정렬을 함에 있어서 어느 시점에서 정렬을 할지 고민하게 된다. 누구나 고민을 하지만 아무나 답변을 얻는 건 아니다. 이럴 때 우리 갓택오버플로께서 길을 보여주신다. 꽤 인상적인 글이긴 하지만 모두가 알다싶이 이 글으느 영어다. 그래서 내가 제대로 이해하기 위해서 해당 글을 번역해보고자 한다. 물론 마이 프렌즈, 번역기와 함께. (일부 번역은 직역이 아닌 문맥에 맞게 내용을 수정 하였습니다. 그래도 어색한 부분은 언제든 지적해주시길.)

 

원문 : database sort vs. programmatic java sort

 


 

🙋 질문 (2009.12.10) 

JPA를 통해 MySQL 데이터베이스에서 데이터를 가져오려고 한다. 이 때 일부 필드값을 기준으로 정렬을 하고자 한다. 아래 두가지 중 어떤 경우가 가장 적절한 정렬일까?

  • 데이터베이스에서 검색한 데이터를 객체 리스트로 획득한 다음, Java API로 정렬하기
  • 데이터베이스에서 쿼리로 바로 정렬하기

 

👍 첫번째 답변 (2009.12.10) 

1000개가 넘는 데이터 중 20개를 화면에 출력하는 경우처럼 데이터 일부를 검색해서 정렬하고 싶은 경우에는 데이터베이스 상에서 정렬하는 것이 좋다. 빠르고 쉽고 한번에 한 페이지의 행을 검색할 수 있다. 

 

Dataset(테이블 내 데이터)가 상당히 작은 경우 복잡한 정렬을 구현해야할 때 코드(Java API)에서 정렬하는 것이 더 편리할 수 있다. 물론 SQL에서도 복잡한 정렬을 할 수 있지만 코드상에서 하는 것만큼 쉽지는 않다.

 

경험상 최고의 규칙은 SQL을 통한 정렬이다. 물론 예외적인 경우에는 코드상에서 정렬을 한다.

 

👉 첫번째 답변의 첫번째 댓글 (2013.03.15)
나는 당신의 규칙에 동의하지 않는다. 데이터 계층에서 정렬하는 것은 비용이 많이 든다. 일반적인 사례는 애플리케이션 계층에서 정렬하는 것과 같이 여러 개의 정렬 순서가 필요할 수 있다. 즉, 프레젠테이션 계층(Java API)에서 데이터의 순서를 변경하는 것이 편의성과 확장성 측면에서 훨씬 더 효율적이다.

 

 

많은 데이터를 다룰수록 복잡하지 않은 정렬도 타이밍에 따라 퍼포먼스가 달라질 수 있다

 

👍 두번째 답변 (2009.12.10) 

일반적으로 SQL 쿼리에서 ORDER BY를 사용하는 것이 좋다. 이렇게 하면 해당 인덱스가 있는 경우 별다른 비용없이 정렬할 수 있다. (최악의 경우, 당신의 코드상에서 평소와 동일한 작업을 수행했음에도 가끔씩 작업 결과가 덜 진행되어 있을 수 있다.)

 

👉 두번째 답변의 첫번째 댓글 (첫번째 답변의 첫번째 댓글 작성자와 동일 인물)
일반적인 사례를 보면 단일 ResultSet은 여러개의 정렬 순서에 대한 요구사항을 가진다. 인덱스가 모든 쿼리의 정렬 요구사항을 다루지 않는 한 인덱스의 이점은 제한된다. 즉, 대부분의 시스템에서는 이 방법은 현실적이지 않다. 사용자가 데이터 계층에서 정렬을 하지 않고 애플리케이션 계층에서 정렬하는 것이 원하는 방식으로 정렬을 변경할 수 있어서 편의성과 확장성의 측면에서 더 합리적이다.

👉 두번째 답변의 두번째 댓글 (두번째 답변의 첫번째 댓글의 반박글)
첫째, 일반적인 사례라는 말에 동의하지 않는다. 애플리케이션에 따라 다르다. 둘째, 빅 데이터의 서브셋(Subset)을 검색하려는 경우라면 어떻게 될까? 데이터 소스에서 수백만 개의 레코드를 가져와 메모리로 처리할 수 있을까? 마지막으로, 나는 데이터 계층에 요청을 보내는 것을 두려워하지 않는다. (예를 들어, 사용자가 다른 검색 기준을 입력하는 경우) 어차피 요청을 자주해야 하기 때문. 또한 검색 속도를 올리고 싶거나 DB만으로 충분하지 않을 때는 항상 캐싱 또는 특수 시스템을 사용할 수 있기 때문이다.

👉 두번째 답변의 세번째 댓글 (두번째 답변의 첫번째 댓글 작성자와 동일 인물)
질문에서 언급한 사례와 연관이 없다. 당신이 제시한 예시의 올바른 결과를 얻으려면 ORDER BY가 필요하다. 질문에 제시된 예시에서의 ORDER BY는 단순히 프레젠테이션 계층을 위한 것이다. 거절할 수 있지만, 전형적인 사용 사례이다. 애플리케이션 계층에서 캐싱 및 정렬할 때 당신은 확장(scaling out)을 할 수 있는 옵션을 사용할 수 있다.

 

 

👍 세번째 답변 (일부만 번역, 2014.02.20) 

여기있는 답변과 마찬가지로 데이터베이스 계층에서의 정렬이 더 빠를 것이라고 생각했다. 아마도 이런 것을 정렬할 때 데이터베이스 계층이 더 잘 맞춰져(tuned) 있기 때문이다. (중간 생략) DB가 정렬을 하는 것이 더 간단하고 오류가 덜 발생한다고 생각한다.

(중간 생략) 내가 테스트한건 아니지만 메모리 소트가 아닌 경우에는 데이터베이스가 적절하다. 벤치마크에서 메모리 소트의 경우는 Java, C, C++이 MySQL보다 우수하다.

 

 

👍 네번째 답변 (일부만 번역, 2009.12.10) 

애플리케이션/데이터베이스에서 정령/페이징을 짜 맞출 수(mix and match) 없음에 유의해야 한다. 이는 데이터베이스에 정렬되지 않은 100행의 데이터를 요청한 후 애플리케이션에서 데이터를 정렬했을 때 예상한 데이터 집합을 얻지 못할 수 있다는 뜻이다. 이게 당연한 것처럼 보일 수 잇지만 적어도 이렇게 언급을 해야할 정도로 실수가 많다.

 

여러 가지 이유로 데이터베이스에서 정렬하고 필터링하는 것이 훨씬 효율적이다. 우선 데이터베이스 엔진은 정렬과 필터링을 수반하는 작업에서 정확히 수행하도록 최적화되어 있다. 그러나 성숙한 데이터베이스 엔진의 정렬, 필터링 및 페이징 성능과 일치하는 코드를 작성할 수 있다고 하더라도 데이터베이스에서 애플리케이션 서버로 전송되는 데이터의 양을 제한하는 것이 더 효율적이기 때문에 데이터베이스에서 정렬등을 수행하는 것이 더 좋다.

 

예를 들어 필터링하기 전에 10,000개의 행이 있고 쿼리 결과로 인해 75개로 줄어들 수 있다. 하지만 클라이언트에서 필터링하면 10,000개의 모든 행의 데이터가 앱 서버의 메모리로 전달된다. 데이터베이스 측에서 필터링을 하면 75개의 행만 전달하면 된다. 이런 부분은 성능과 확장성에 큰 영향을 미칠 수 있다.

 

 

👍 다섯번째 답변 (2009.12.10) 

데이터베이스가 정렬하는 것이 더 빠를 것이라고 확신한다. 검색 알고리즘을 완벽하게 만들고 최적화하는 데 많은 시간을 소비하는 엔지니어도 있다. 이렇게까지 하지 않더라도 몇 가지 계산을 더 추가할 수 있는 자신만의 정렬 알고리즘을 구현해야 할 수도 있다.

 


 

대부분은 데이터베이스에서 정렬 및 필터를 하도록 권장하고 있다. 이는 성능적인 이유도 있지만 그 외 안정성과 확장성을 고려한 이슈이기도 하다. 하지만 코드상 정렬을 무조건적으로 피하지는 않는다. 상황에 따라 복잡한 정렬을 요구한다면 코드상에서 정렬을 할 수 있다. 이런 점을 충분히 인지하고 적절한 정렬을 적용하면 된다.

728x90
반응형