-
由 Ryuta Kamizono 提交于
Before IN clause optimization 70ddb8a7, Active Record had generated an SQL with binds when `prepared_statements: true`: ```ruby # prepared_statements: true # # SELECT `authors`.* FROM `authors` WHERE `authors`.`id` IN (?, ?, ?) # # prepared_statements: false # # SELECT `authors`.* FROM `authors` WHERE `authors`.`id` IN (1, 2, 3) # Author.where(id: [1, 2, 3]).to_a ``` But now, binds in IN clause is substituted regardless of whether `prepared_statements: true` or not: ```ruby # prepared_statements: true # # SELECT `authors`.* FROM `authors` WHERE `authors`.`id`IN (1,2,3) # # prepared_statements: false # # SELECT `authors`.* FROM `authors` WHERE `authors`.`id`IN (1,2,3) # Author.where(id: [1, 2, 3]).to_a ``` I suppose that is considered as a regression for the context: > While I would prefer that we fix/avoid the too-many-parameters problem, but I don't like the idea of globally ditching bind params for this edge case... we're getting to the point where I'd almost consider anything that doesn't use a bind to be a bug. https://github.com/rails/rails/pull/33844#issuecomment-421000003 This makes binds consider whether `prepared_statements: true` or not (i.e. restore the original behavior as before), but still gain that optimization when need the substitute binds (`prepared_statements: false`, `relation.to_sql`). Even when `prepared_statements: true`, it still much faster than before by optimized (bind node less) binds generation. ```ruby class Post < ActiveRecord::Base end ids = (1..1000).each.map do |n| Post.create!.id end puts "prepared_statements: #{Post.connection.prepared_statements.inspect}" Benchmark.ips do |x| x.report("where with ids") do Post.where(id: ids).to_a end end ``` * Before (200058b0) `prepared_statements: true`: ``` Warming up -------------------------------------- where with ids 6.000 i/100ms Calculating ------------------------------------- where with ids 63.806 (± 7.8%) i/s - 318.000 in 5.015903s ``` `prepared_statements: false`: ``` Warming up -------------------------------------- where with ids 7.000 i/100ms Calculating ------------------------------------- where with ids 73.550 (± 8.2%) i/s - 371.000 in 5.085672s ``` * Now with this change `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 ``` `prepared_statements: false`: ``` Warming up -------------------------------------- where with ids 10.000 i/100ms Calculating ------------------------------------- where with ids 104.335 (± 8.6%) i/s - 520.000 in 5.026425s ```
157f6a6e