Rails의 AR이 대량의 데이터를 읽어올때 생기는 속도 문제.

DB에는 약 500,000개의 rows가 있다.

A액션을 하게되면
DB에 쿼리를 날리게 되고 약 75,000개의 rows가 return된다.
이 데이터를 가지고 알고리즘을 돌리게 되는데
문제는 고작 75,000개의 데이터를 처리하는데 시간이 너무 오래 걸리는 것이다.
약 80초가 걸리는데 이건 뭔가 문제가 있다.
SELECT 쿼리는 최적화가 되어있는 상태로 문제가 없었다.

도대체 어디서 이렇게 시간을 많이 잡아먹나 확인을 해보니
DB에 쿼리를 날리고 난 후 알고리즘 들어가기 전까지가 엄청나게 많은 시간을 잡아먹는 것이었다.

ActiveRecord가 DB 결과값을 변환하는데 걸린 시간: 약 75초 알고리즘 로직이 돌아간 시간: 약 3.4초

ActiveRecord가 DB 결과값을 변환하는데 걸린 시간: 약 75초
알고리즘 로직이 돌아간 시간: 약 3.4초
총 연산시간: 약 80초

쿼리도 문제없고, 알고리즘도 문제없다.
하지만 둘 사이에 알 수 없는 작업으로 시간이 오래 걸린다면..
의심해볼 건 ORM.. 바로 ActiveRecord(이하 AR)

그래서 과감하게 AR을 버리고 mysql2(gem)만 이용하도록 수정을 했다. (mysql2… mysql을 사용하면 필수적으로 설치하는 그 gem 맞다.)
그랬더니 시간이 급속적으로 향상되었다.

DB 결과값을 변환하는데 걸린 시간: 약 0.3초
알고리즘 로직이 돌아간 시간: 약 0.7초
총 연산시간: 약 1.1초

80초에서 1초로 줄었. 응?
눈을 비비고 다시 한번 확인.
혹시나 싶어서 여러번 A액션 재실행.
헐.. 대박 ㅋㅋ
말도 안되는 성과 도출!
쩔어 쩔어

여기서 주목할 점은 알고리즘부분까지 소모시간이 줄었다는 것이다.
이것 또한 같은 이유로 인함인데
여기서 AR의 동작원리라고 하기엔 좀 거창하지만를 이해할 필요가 있는데
mysql2은 결과값을 해쉬(Hash)로 보관하게 되는데
(엄밀히 따지면 Mysql2::Result에 Hash형태로 각 row가 보관이 된다.)
사실 AR도 mysql2를 이용해서 넘겨받은 해쉬를 AR(데이터 타입)로 변환하게 된다.
알다시피 AR(데이터 타입)에는 각종 모듈 및 헬퍼등 살이 디룩디룩 찌고 다리가 4개인 우르곳이라면
반면 해쉬는 Ruby Core lib 모듈 포함된 녀석으로 아주 앙상하게 마른 뼈밖에 없는 피들스틱이랄까?
(Rails에서 사용하는 해쉬는 포식시켜 스택이 3정도 쌓은 초가스랄까? 뭐래는겨 ㅋㅋㅋ)

결론
결국 AR이 무겁고, 이렇게 무거운 AR을 사용하기 때문에 생기는 이슈인 것이다.
그렇다고 AR이 나쁘다! 구리다! 하자다! 라고 하기엔 어폐가 있다.
Rails는 웹 개발 프래임웍이다. 웹 개발이 목적이고 이를 위해 만들어진 ORM이 AR이다.
이런 AR에게 데이타를 몇 만건씩 가져오는걸 기대하는것 자체가 문제가 있다.
보편적인 웹 서비스에선 몇 만건씩 데이터를 가져오는 일 따위는 일어나지 않을것이니

그러므로 배치성 작업 혹은 많은 량의 데이트를 컨트롤해야 하는 경우에
Rails가 필요 없다면 그냥 Ruby로만 짜는것이 좋고,
Rails를 써야만 한다면 AR사용은 고민해볼 필요가 있다.

덤.
3,500개의 rows를 AR이 변환하는데 걸리는데 1.8초정도 소모가 되었다.
고작 3,500개밖에 안되는데도 약 2초가 소모된다.
소량의 작업에선 속도가 문제가 안되지만..
1,000건이 넘어갈 경우에는 꼭 테스트를 해보길 권장한다.

+ 추가
아직 확인은 못해봤지만.. Sangmin Ryu님의 실서비스 테스트 결과를 보면 속도가 느리지 않다
물런 하드웨어 스펙이 차이가 좀 많이 나는것 같지만.. ㅋㅋ 그걸로 설명하기엔 속도차가 너무 크다.
모델의 덩치와도 관계가 있다고 추측된다.
일단 해당 이슈가 발생한 모델의 필드가 약 50개이고 그 중 10개는 text이다.
뿐만 아니라 메소드 또한 많은데 이 모델의 소스 코드가 약 600줄정도 된다.

AR이 해야할 작업이 많아져서 속도가 느려졌던걸로 판단된다.

+ 추가
AR 속도 테스트

Rails의 AR이 대량의 데이터를 읽어올때 생기는 속도 문제.”에 대한 1개의 생각

  1. 핑백: Rails AR 속도 테스트 | LAMPist LOG

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중