[RUBY-ON-RAILS] 조건을 가진 열에 대한 카운터 캐시?
RUBY-ON-RAILS조건을 가진 열에 대한 카운터 캐시?
나는 카운터 캐싱의 개념과 내 응용 프로그램의 메인 페이지 중 하나에 대한 몇 가지 천문학적로드 시간에 새로운 오전, 나는 그것을 가야 할 필요가있다 생각합니다.
카운터의 대부분은 내가 연결된 특정 (단순) 조건을 구현해야 캐시합니다. 예를 들어, 다음은 일반적인 쿼리는 다음과 같습니다
@projects = employee.projects.where("complete = ?", true).count
나는 양식을 표시 할 때 위의와 N + 1 쿼리 문제에 걸림돌하고 그 회사가 모든 직원에 대한 목록 프로젝트 계산됩니다.
난 정말이 날 수정하시기 바랍니다 그래서 뭘하는지 모르겠어요!
# new migration
add_column :employees, :projects_count, :integer, :default => 0, :null => false
# employee.rb
has_many :projects
# project.rb
belongs_to :employee, :counter_cache => true
마이그레이션 후 ... 모든 I 필요가해야 할 것입니다?
로드 시간을 최소화하기 위해 어떻게 내가 그렇게 언급 한 조건에서 작동 할 수 있습니까?
해결법
-
==============================
1.counter_cache와 조건에 관해서,이 블로그 게시물을 읽을 것입니다.
counter_cache와 조건에 관해서,이 블로그 게시물을 읽을 것입니다.
당신이해야 할 한 가지는 마이그레이션 파일에 다음을 추가 할 수 있습니다 :
add_column :employees, :projects_count, :integer, :default => 0, :null => false Employee.reset_column_information Employee.all.each do |e| Employee.update_counters e.id, :projects_count => e.projects.length end
당신 그래서 현재 프로젝트의 수는 각 직원 객체와 관련된 새로운 projects_count로 마이그레이션받을 수 있습니다. 그 후, 당신은 갈 수 있어야한다.
-
==============================
2.counter_culture 보석을 확인합니다 :
counter_culture 보석을 확인합니다 :
counter_culture :category, column_name: Proc.new {|project| project.complete? ? 'complete_count' : nil }
-
==============================
3.당신은 "counter_cache"이 아니라 사용자 정의 열을 사용하지 않아야합니다 :
당신은 "counter_cache"이 아니라 사용자 정의 열을 사용하지 않아야합니다 :
rails g migration AddCompletedProjectsCountToEmployees completed_projects_count:integer
(추가, 상기 add_column 라인에 기본 => 0 당신이 원하는 경우)
rake db:migrate
다음 콜백을 사용
class Project < ActiveRecord::Base belongs_to :employee after_save :refresh_employee_completed_projects_count after_destroy :refresh_employee_completed_projects_count def refresh_employee_completed_projects_count employee.refresh_completed_projects_count end end class Employee has_many :projects def refresh_completed_projects_count update(completed_projects_count:projects.where(completed:true).size) end end
열을 추가 한 후, 당신은 (DEF까지의) 콘솔 또는 마이그레이션 파일에 초기화해야한다 :
Employee.all.each &:refresh_completed_projects_count
그런 다음 코드에서, 당신은 액세스하기 위해 employee.completed_projects_count 호출해야합니다 그것
-
==============================
4.대신 update_counters의 난 update_all 사용
대신 update_counters의 난 update_all 사용
당신은 Employee.reset_column_information 라인이 필요하지 않습니다 그리고 당신은 하나의 데이터베이스 호출을하고 있기 때문에 더 빠른
Employee.update_all("projects_count = ( SELECT COUNT(projects.id) FROM projects WHERE projects.employee_id = employees.id AND projects.complete = 't')")
from https://stackoverflow.com/questions/5347323/counter-cache-for-a-column-with-conditions by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] 조건에 따라 경로를 레일 (0) | 2020.02.20 |
---|---|
[RUBY-ON-RAILS] RSpec에와라는 이름의 경로 (0) | 2020.02.20 |
[RUBY-ON-RAILS] 액티브 :: 자료에 대한 정의되지 않은 방법 raise_in_transactional_callbacks = ': 클래스 (NoMethodError) (0) | 2020.02.20 |
[RUBY-ON-RAILS] 미디어 파일 스트림 또는 SEND_DATA send_file 방법을 통해 바이트 범위 요청을 수락 레일 (0) | 2020.02.20 |
[RUBY-ON-RAILS] 레일에 루비 - 모델에서 액세스 컨트롤러 변수 (0) | 2020.02.20 |