Skip to content

Instantly share code, notes, and snippets.

@raggi
Created March 16, 2012 00:48
Show Gist options
  • Select an option

  • Save raggi/2047974 to your computer and use it in GitHub Desktop.

Select an option

Save raggi/2047974 to your computer and use it in GitHub Desktop.
Mysql2 Column Cache for Rails 3.0.12
# = 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
@mehagar
Copy link
Copy Markdown

mehagar commented Jun 15, 2020

Is this still needed for Rails 4.2 and later?

@raggi
Copy link
Copy Markdown
Author

raggi commented Jun 15, 2020

No idea, sorry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment