提交 dbda5feb 编写于 作者: R Ryuta Kamizono

Use statement cache for `find_by(author: david)`

```ruby
ActiveRecord::Schema.define do
  create_table :posts, force: true do |t|
  end

  create_table :comments, force: true do |t|
    t.belongs_to :post
  end
end

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

post = Post.create!

Benchmark.ips do |x|
  x.report("find_by post") { Comment.find_by(post: post) }
end
```

Before:

```
Warming up --------------------------------------
        find_by post   395.000  i/100ms
Calculating -------------------------------------
        find_by post      4.026k (± 3.1%) i/s -     20.145k in   5.008059s
```

After:

```
Warming up --------------------------------------
        find_by post     1.183k i/100ms
Calculating -------------------------------------
        find_by post     11.859k (± 2.5%) i/s -     60.333k in   5.090685s
```
上级 60bfed90
......@@ -202,11 +202,20 @@ def find_by(*args) # :nodoc:
hash = args.first
return super unless Hash === hash
values = hash.values
values = hash.values.map! { |value| value.is_a?(Base) ? value.id : value }
return super if values.any? { |v| StatementCache.unsupported_value?(v) }
# We can't cache Post.find_by(author: david) ...yet
keys = hash.keys.map! { |key| attribute_aliases[name = key.to_s] || name }
keys = hash.keys.map! do |key|
attribute_aliases[name = key.to_s] || begin
reflection = _reflect_on_association(name)
if reflection&.belongs_to? && !reflection.polymorphic?
reflection.join_foreign_key
else
name
end
end
end
return super unless keys.all? { |k| columns_hash.key?(k) }
statement = cached_find_by_statement(keys) { |params|
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册