mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add add_binds
to bulk binds processing for performance
Before with `prepared_statements: true`: ``` Warming up -------------------------------------- where with ids 9.000 i/100ms Calculating ------------------------------------- where with ids 91.992 (± 7.6%) i/s - 459.000 in 5.020817s ``` Now with `prepared_statements: true`: ``` Warming up -------------------------------------- where with ids 10.000 i/100ms Calculating ------------------------------------- where with ids 99.393 (± 8.0%) i/s - 500.000 in 5.069280s ```
This commit is contained in:
parent
157f6a6efe
commit
2b35775fbe
7 changed files with 49 additions and 14 deletions
|
@ -50,8 +50,13 @@ module ActiveRecord
|
|||
|
||||
def sql_for(binds, connection)
|
||||
val = @values.dup
|
||||
casted_binds = binds.map(&:value_for_database)
|
||||
@indexes.each { |i| val[i] = connection.quote(casted_binds.shift) }
|
||||
@indexes.each do |i|
|
||||
value = binds.shift
|
||||
if ActiveModel::Attribute === value
|
||||
value = value.value_for_database
|
||||
end
|
||||
val[i] = connection.quote(value)
|
||||
end
|
||||
val.join
|
||||
end
|
||||
end
|
||||
|
@ -75,6 +80,15 @@ module ActiveRecord
|
|||
self
|
||||
end
|
||||
|
||||
def add_binds(binds)
|
||||
@binds.concat binds
|
||||
binds.size.times do |i|
|
||||
@parts << ", " unless i == 0
|
||||
@parts << Substitute.new
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def value
|
||||
[@parts, @binds]
|
||||
end
|
||||
|
|
|
@ -16,6 +16,11 @@ module Arel # :nodoc: all
|
|||
self
|
||||
end
|
||||
|
||||
def add_binds(binds)
|
||||
@binds.concat binds
|
||||
self
|
||||
end
|
||||
|
||||
def value
|
||||
@binds
|
||||
end
|
||||
|
|
|
@ -22,6 +22,12 @@ module Arel # :nodoc: all
|
|||
self
|
||||
end
|
||||
|
||||
def add_binds(binds, &block)
|
||||
left.add_binds(binds, &block)
|
||||
right.add_binds(binds, &block)
|
||||
self
|
||||
end
|
||||
|
||||
def value
|
||||
[left.value, right.value]
|
||||
end
|
||||
|
|
|
@ -17,6 +17,11 @@ module Arel # :nodoc: all
|
|||
@bind_index += 1
|
||||
self
|
||||
end
|
||||
|
||||
def add_binds(binds, &block)
|
||||
self << (@bind_index...@bind_index += binds.size).map(&block).join(", ")
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,6 +20,10 @@ module Arel # :nodoc: all
|
|||
self << quoter.quote(bind)
|
||||
end
|
||||
|
||||
def add_binds(binds)
|
||||
self << binds.map { |bind| quoter.quote(bind) }.join(", ")
|
||||
end
|
||||
|
||||
def value
|
||||
delegate.value
|
||||
end
|
||||
|
|
|
@ -41,10 +41,6 @@ module Arel # :nodoc: all
|
|||
visit(o.expr, collector) << " )"
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_BindParam(o, collector, value = o.value)
|
||||
collector.add_bind(value) { |i| "$#{i}" }
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_GroupingElement(o, collector)
|
||||
collector << "( "
|
||||
visit(o.expr, collector) << " )"
|
||||
|
@ -92,6 +88,11 @@ module Arel # :nodoc: all
|
|||
collector << " NULLS LAST"
|
||||
end
|
||||
|
||||
BIND_BLOCK = proc { |i| "$#{i}" }
|
||||
private_constant :BIND_BLOCK
|
||||
|
||||
def bind_block; BIND_BLOCK; end
|
||||
|
||||
# Used by Lateral visitor to enclose select queries in parentheses
|
||||
def grouping_parentheses(o, collector)
|
||||
if o.expr.is_a? Nodes::SelectStatement
|
||||
|
|
|
@ -336,13 +336,8 @@ module Arel # :nodoc: all
|
|||
|
||||
if values.empty?
|
||||
collector << @connection.quote(nil)
|
||||
elsif @connection.prepared_statements
|
||||
values.each_with_index do |v, i|
|
||||
collector << ", " unless i == 0
|
||||
visit_Arel_Nodes_BindParam(nil, collector, v)
|
||||
end
|
||||
else
|
||||
collector << values.map! { |v| @connection.quote(v) }.join(", ")
|
||||
collector.add_binds(values, &bind_block)
|
||||
end
|
||||
|
||||
collector << ")"
|
||||
|
@ -695,8 +690,13 @@ module Arel # :nodoc: all
|
|||
collector << quote_table_name(join_name) << "." << quote_column_name(o.name)
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_BindParam(o, collector, value = o.value)
|
||||
collector.add_bind(value) { "?" }
|
||||
BIND_BLOCK = proc { "?" }
|
||||
private_constant :BIND_BLOCK
|
||||
|
||||
def bind_block; BIND_BLOCK; end
|
||||
|
||||
def visit_Arel_Nodes_BindParam(o, collector)
|
||||
collector.add_bind(o.value, &bind_block)
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_SqlLiteral(o, collector)
|
||||
|
|
Loading…
Reference in a new issue