1. 05 5月, 2020 4 次提交
  2. 04 5月, 2020 2 次提交
  3. 03 5月, 2020 5 次提交
  4. 02 5月, 2020 5 次提交
  5. 01 5月, 2020 6 次提交
    • R
      Remove internal `without_transaction_enrollment` callbacks · 75873d8f
      Ryuta Kamizono 提交于
      I've found the internal `without_transaction_enrollment` callbacks which
      have not been newly used over five years, when I tried to work reverting
      #9068 (https://github.com/rails/rails/pull/36049#issuecomment-487318060).
      
      I think that we will never make that callbacks public, since the
      mechanism of `without_transaction_enrollment` is too implementation
      specific, at least before #9068, records in a transaction had enrolled
      all into the transaction.
      
      That callbacks was introduced at #18936 to make `touch_later` #19324,
      but I think that the internal callbacks is overkill to just make the
      `touch_later` only, and invoking the extra callbacks also have a little
      overhead even if we haven't used that.
      
      So I think we can remove the internal callbacks for now, until we will
      come up with a good use for that callbacks.
      75873d8f
    • J
      Also batch attribute readers and writers · d12418a7
      Jean Boussier 提交于
      d12418a7
    • R
      Avoid quite useless loop in `find_by_sql` · 71e45582
      Ryuta Kamizono 提交于
      `column_types` is empty except PostgreSQL adapter, and
      `attribute_types.each_key { |k| column_types.delete k }` is also empty
      even if PostgreSQL adapter almost all case, so that code is quite
      useless. This improves performance for `find_by_sql` to avoid that
      useless loop as much as possible.
      
      ```ruby
      ActiveRecord::Schema.define do
        create_table :active_storage_blobs do |t|
          t.string   :key,          null: false
          t.string   :filename,     null: false
          t.string   :content_type
          t.text     :metadata
          t.string   :service_name, null: false
          t.bigint   :byte_size,    null: false
          t.string   :checksum,     null: false
          t.datetime :created_at,   null: false
      
          t.index [ :key ], unique: true
        end
      end
      
      class ActiveStorageBlob < ActiveRecord::Base
      end
      
      Benchmark.ips do |x|
        x.report("find_by") { ActiveStorageBlob.find_by(id: 1) }
      end
      ```
      
      Before:
      
      ```
      Warming up --------------------------------------
                   find_by     1.256k i/100ms
      Calculating -------------------------------------
                   find_by     12.595k (± 3.4%) i/s -     64.056k in   5.091599s
      ```
      
      After:
      
      ```
      Warming up --------------------------------------
                   find_by     1.341k i/100ms
      Calculating -------------------------------------
                   find_by     13.170k (± 3.5%) i/s -     67.050k in   5.097439s
      ```
      
      To avoid column types loop for PostgreSQL adapter, this skips returning
      additional column types if a column has already been type casted by pg
      decoders. Fortunately this fixes #36186 partly for common types.
      71e45582
    • R
      Replace `result_as_array` by type mapping · 348e142b
      Ryuta Kamizono 提交于
      348e142b
    • R
    • R
      Should not rely on the global `Arel::Table.engine` in the framework · bc99e401
      Ryuta Kamizono 提交于
      Relying on the `Arel::Table.engine` is convenient if an app have only a
      single kind of database, but if not so, the global state is not always
      the same with the current connection.
      bc99e401
  6. 30 4月, 2020 1 次提交
    • R
      Deprecate `allowed_index_name_length` in `DatabaseLimits` · ab2d859e
      Ryuta Kamizono 提交于
      `allowed_index_name_length` was used for internal temporary operations
      in SQLite3, since index name in SQLite3 must be globally unique and
      SQLite3 doesn't have ALTER TABLE feature (so it is emulated by creating
      temporary table with prefix).
      
      `allowed_index_name_length` was to reserve the margin for the prefix,
      but actually SQLite3 doesn't have a limitation for identifier name
      length, so the margin has removed at 36901e6e.
      
      Now `allowed_index_name_length` is no longer relied on by any adapter,
      so I'd like to remove the internal specific method which is no longer
      used.
      ab2d859e
  7. 29 4月, 2020 3 次提交
    • R
      Remove useless type cast on aggregated value · e10765cf
      Ryuta Kamizono 提交于
      Related #39039.
      
      Currently PostgreSQL adapter is the only adapter that rely on type
      casting by `result.column_types`, now the adapter can return numeric
      value without type casting by Active Record side.
      So we can remove that useless type cast on aggregated value.
      e10765cf
    • R
      Do not need `- 2` margin for `allowed_index_name_length` in SQLite3 · 36901e6e
      Ryuta Kamizono 提交于
      Actually SQLite3 doesn't have a limitation for identifier name length,
      so do not need `- 2` margin internally to perform temporary rename
      operations.
      36901e6e
    • R
      PERF: Improve performance of where when using an array of values · c3a2b54b
      Ryuta Kamizono 提交于
      This is a smaller alternative of performance improvement, without
      refactoring type casting mechanism #39009.
      
      This is relatively a smaller change (but about 40% faster than before),
      so I think this could be easier reviewed without discuss about
      refactoring type casting mechanism.
      
      This just makes `attribute.in(values)` less allocation from an array of
      casted nodes to one casted array node.
      
      ```ruby
      ids = (1..1000).each.map do |n|
        Post.create!.id
      end
      
      Benchmark.ips do |x|
        x.report("where with ids") do
          Post.where(id: ids).to_a
        end
      
        x.report("where with sanitize") do
          Post.where(ActiveRecord::Base.sanitize_sql(["id IN (?)", ids])).to_a
        end
      
        x.compare!
      end
      ```
      
      Before:
      
      ```
      Warming up --------------------------------------
            where with ids     7.000  i/100ms
       where with sanitize    13.000  i/100ms
      
      Calculating -------------------------------------
            where with ids     70.661  (± 5.7%) i/s -    357.000  in   5.072771s
       where with sanitize    130.993  (± 7.6%) i/s -    663.000  in   5.096085s
      
      Comparison:
       where with sanitize:      131.0 i/s
            where with ids:       70.7 i/s - 1.85x  slower
      ```
      
      After:
      
      ```
      Warming up --------------------------------------
            where with ids    10.000  i/100ms
       where with sanitize    13.000  i/100ms
      
      Calculating -------------------------------------
            where with ids     98.174  (± 7.1%) i/s -    490.000  in   5.012851s
       where with sanitize    132.289  (± 8.3%) i/s -    663.000  in   5.052728s
      
      Comparison:
       where with sanitize:      132.3 i/s
            where with ids:       98.2 i/s - 1.35x  slower
      ```
      c3a2b54b
  8. 28 4月, 2020 2 次提交
    • R
      Improve performance for `scope_for_create` · b66235d4
      Ryuta Kamizono 提交于
      ```ruby
      class Post < ActiveRecord::Base
      end
      
      posts = Post.where(id: 1, title: "foo")
      
      Benchmark.ips do |x|
        x.report("scope_for_create") { posts.scope_for_create }
      end
      ```
      
      Before:
      
      ```
      Warming up --------------------------------------
          scope_for_create    30.125k i/100ms
      Calculating -------------------------------------
          scope_for_create    334.033k (± 4.4%) i/s -      1.687M in   5.060493s
      ```
      
      After:
      
      ```
      Warming up --------------------------------------
          scope_for_create    35.088k i/100ms
      Calculating -------------------------------------
          scope_for_create    388.603k (±11.8%) i/s -      1.930M in   5.080998s
      ```
      b66235d4
    • R
      Refactor Arel node `Casted`, `Quoted`, and `BindParam` · 280d6eb2
      Ryuta Kamizono 提交于
      Define `value_for_database` and `value_before_type_cast` methods, and
      use those.
      280d6eb2
  9. 27 4月, 2020 3 次提交
  10. 26 4月, 2020 1 次提交
    • R
      More concise Arel `Or` ast and make `Or` visitor non recursive · 7d3bff1f
      Ryuta Kamizono 提交于
      Before this, 1000 `Or` nodes will raise "stack level too deep" due to
      visiting too deep Arel ast.
      
      This makes more concise Arel `Or` ast and `Or` visitor non recursive if
      `Or` nodes are adjoined, as a result, "stack level too deep" is no
      longer raised.
      
      ```ruby
      class Post < ActiveRecord::Base
      end
      
      posts = (0..500).map { |i| Post.where(id: i) }
      
      Benchmark.ips do |x|
        x.report("inject scopes") { posts.inject(&:or).to_sql }
      end
      ```
      
      Before:
      
      ```
      Warming up --------------------------------------
            where with ids     9.000  i/100ms
      Calculating -------------------------------------
            where with ids     96.126  (± 2.1%) i/s -    486.000  in   5.058960s
      ```
      
      After:
      
      ```
      Warming up --------------------------------------
             inject scopes    10.000  i/100ms
      Calculating -------------------------------------
             inject scopes    101.714  (± 2.9%) i/s -    510.000  in   5.018880s
      ```
      
      Fixes #39032.
      7d3bff1f
  11. 25 4月, 2020 5 次提交
  12. 24 4月, 2020 1 次提交
  13. 23 4月, 2020 2 次提交