Created
March 16, 2012 00:48
-
-
Save raggi/2047974 to your computer and use it in GitHub Desktop.
Mysql2 Column Cache for Rails 3.0.12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# = MONKEY PATCH: Memoize Mysql2 Columns | |
# | |
# Reduces SHOW FIELDS selects in production to essentially 0 calls. | |
# | |
# == Reason: | |
# | |
# * We have some pages that are (with rails 3.0.12) generating nearly 1200 SHOW | |
# FIELDS sql statements. | |
# * These come from ActiveRecord::Associations during complex join semantics. | |
# * Esentially, through some relations, Arel::Table instances don't have | |
# pre-cached column data, or access to the related AR::Base instance. | |
# * We have at least some routes that hit this many times. | |
# | |
# == Notes: | |
# | |
# * You cannot observe these SHOW FIELDS through the rails logs. They were | |
# observed using strace(1) on production systems, and noted due to the volume | |
# of calls. | |
# * This seems to occur on some quite heavily abstracted code (cross-engine | |
# code), and may not happen in "more normal" parts of the app. | |
# * The performance profile when running with a mysql server on localhost on an | |
# SSD will be far less drastic than against EBS on a different EC2 host, | |
# especially when a lot of calls are generated. | |
# | |
# == Caveats: | |
# | |
# * This is enabled for both production and test environments in order that we | |
# catch any issues that might arise from it. | |
# * It is disabled for development because the Mysql2Adapter will not be | |
# reloaded between model loads, which means new columns won't be found. It | |
# could also lead to other confusion for dev mode. | |
# | |
# == Original backtrace: | |
# | |
# N.B. Abbreviated: | |
# | |
# gems/arel-2.0.10/lib/arel/table.rb:97:in `columns' | |
# gems/arel-2.0.10/lib/arel/table.rb:104:in `[]' | |
# gems/activerecord-3.0.10/lib/active_record/associations.rb:2204:in `association_join' | |
# gems/activerecord-3.0.10/lib/active_record/relation/query_methods.rb:256:in `build_joins' | |
# gems/activerecord-3.0.10/lib/active_record/relation/query_methods.rb:254:in `each' | |
# gems/activerecord-3.0.10/lib/active_record/relation/query_methods.rb:254:in `build_joins' | |
# gems/activerecord-3.0.10/lib/active_record/relation/query_methods.rb:176:in `build_arel' | |
# gems/activerecord-3.0.10/lib/active_record/relation/query_methods.rb:149:in `arel' | |
# gems/activerecord-3.0.10/lib/active_record/relation.rb:321:in `to_sql' | |
# gems/activerecord-3.0.10/lib/active_record/relation/calculations.rb:207:in `execute_simple_calculation' | |
# gems/activerecord-3.0.10/lib/active_record/relation/calculations.rb:182:in `perform_calculation' | |
# gems/activerecord-3.0.10/lib/active_record/relation/calculations.rb:152:in `calculate' | |
# gems/activerecord-3.0.10/lib/active_record/relation/calculations.rb:58:in `count' | |
# gems/activerecord-3.0.10/lib/active_record/relation.rb:92:in `empty?' | |
# gems/activerecord-3.0.10/lib/active_record/relation.rb:100:in `any?' | |
# app/models/item.rb:158:in `votable_by?' | |
# ruby/1.8/delegate.rb:140:in `__send__' | |
# ruby/1.8/delegate.rb:140:in `votable_by?' | |
# ruby/1.8/delegate.rb:140:in `__send__' | |
# ruby/1.8/delegate.rb:140:in `votable_by?' | |
# app/liquid/gallery/drops/entry_drop.rb:47:in `_unmemoized_completed' | |
# | |
# == Original strace counts: | |
# | |
# ~ % grep 'SHOW FIELDS' request.txt| wc -l | |
# 1188 | |
# ~ % grep 'SHOW FIELDS' request.txt| sort | uniq| wc -l | |
# 5 | |
# | |
# == Additional Notes: | |
# | |
# * Some of this code changes by Rails 3.2, semantics may also. | |
# * It is possible that AR::Association is patchable, certainly at least one | |
# call to Arel::Table.new does not pass a :columns option that could be | |
# populated from objects in the scope. | |
# * It is also conceivable that this could be a reasonable configurable option | |
# for rails itself, something like +config.cache_sql_adapter_columns+. | |
# | |
if Rails.application.config.cache_classes | |
class ActiveRecord::ConnectionAdapters::Mysql2Adapter | |
extend ActiveSupport::Memoizable | |
memoize :columns | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No idea, sorry.