공통
- DB SQL발행 횟수를 줄이기
Select
- N+1을 예방하기
includes, preload, eager_load를 사용해서 쿼리를 캐시하기
includes : 테이블 별로 SQL로 검색해서 캐시, 조건에 따라 SQL 1개만 발행
preload : 테이블 별로 SQL로 검색해서 캐시, 관련테이블은 조건 지정 불가능
eager_load : 관련된 테이블을 left join으로 검색해서 캐시, SQL 1개만 발행
@user = User.includes(:UserDetail) - 검색시 불필요한 join이나 eagal_load를 줄이기
단순 Copy & Paste 혹은 코드 수정으로 인해 사용하지 않는 테이블을 지우기 - 건수 검색할때는 length를 사용하기
count : 실행할 때 마다 SQL발행
size : 실행할 때 마다 SQL발행, length 실행 후에는 메모리에서 load
length : 2번째 이후 SQL발행안함, 메모리에 cache - 검색해서 반복문 처리할때, 전체 검색이 아닌 일정건수 끊어서 검색하기
User.find_in_batches(batch_size: 1000) do |user|
1000건씩 끊어서 검색해서 반복처리 - 검색시 select로 Colums 지정하기
검색결과 : ActiveRecord - 검색시 pluck로 Column 지정하기
검색결과 : Array<String>, Array<Array<String>>
pluck에 적은 Column순서대로 정렬됨
Array<String> → Array<Hash> 로 만들어 이용하기
레코드가 많고 컬럼이 많은경우에 pluck사용하는 것 만으로도 1GB 이상의 메모리를 줄일 수 있음
User.all.map(&:name) → User.pluck(:name) - 검색 후 루프 처리하는경우에 ActiveRecord 참조하는 것 만으로도 메모리가 계속 증가하므로
위 8. 처럼 hash로 만들어서 처리하기 - 똑같은 검색을 여러번 하는 경우에는 결과를 메모리화 하기
전
def user
@user = User.where(id: ids)
end
후
def user
@user ||= User.where(id: ids)
end
INSERT, UPDATE, UPSERT
- 처리 속도 순서
처리에 따라 batch_size, validtion, callback 등 지원하는 기능이 다름.
1 INSERT SQL직접 실행 : connection.execute sql
2 insert_all
3 import
4 create - INSERT, UPDATE 복수건 묶어서 처리하기
1만건 처리할때, SQL을 1만건 발행하지 않기(create를 1만건 반복)
insert_all, update_all, bulk_import를 이용해서 묶어서 처리하기
https://github.com/zdennis/activerecord-import - activerecord-import이용시, INSERT, UPDATE를 Hash로 하기
메모리도 줄고, 처리속도도 빨라짐 - 처리 건수를 제한하기
몇만, 몇십만건을 한번에 처리하지 않기
each_slice로 건수를 나눠서 처리하기
※ Postgresql에서 복수건 검색하고, 갱신할때 최대 파라미터는 65535건.
예 ) model.where(id: ids).update_all(・・・) 할때 ids.length > 65535 인 경우 error
'Ruby' 카테고리의 다른 글
unicode normalizeのform (0) | 2024.06.10 |
---|---|
rsepc mock 메소드 내부 확인 (0) | 2023.10.23 |