

環境: ruby2.1.3, rails4.2, activerecord-sqlserver-adapter4.1

20個ほどあるデータベースを、あちこち切り替えながら処理しなくてはならない場合。  
まず接続情報を格納した配列(specs)を用意して、

[code]

    Benchmark.bm do |x|
      100.times{ x.report{ ActiveRecord::Base.establish_connection(specs.sample) } }
    end
    
[/code]

と確認してみたところ。どうにも0.9秒～1.2秒かかっているようです。  
単体コストはともかくとして、最初にガッツリ全部の接続先をキープして、  
クエリを投げる先だけ変えるような感じで切替コストを下げることは、できないものでしょうか。

以下、考え事：  
(接続モデルをDB分作って、各モデルが継承という手も考えたのですが。全てのモデルファイルのコピーを20個ずつ作るのもおかしな話に感じます。動的にモデルを複製して継承しなおすという事も考えたのですが最後の手段にしたいなぁと)


CC BY-SA 3.0
2015-03-11T08:38:28.533
7779
2015-04-10T12:02:20.223
8335
question
ruby-on-rails rails-activerecord
railsで複数DBを素早く切り替えるためには?


僕自身は実際にやったことはないですし、ご質問の状況と異なる部分もありますが、このページの内容が結構近いんじゃないかと思いました。

<https://stackoverflow.com/questions/16775795/rails-switch-connection-on-each-
request-but-keep-a-connection-pool>

上の記事から引用したコード

[code]

    # A model class that connects to a different DB depending on the subdomain 
    # we're in
    class ModelBase < ActiveRecord::Base
      self.abstract_class = true
      self.connection_handler = CustomConnectionHandler.new
    end
    
    # ...
    
    class CustomConnectionHandler < ActiveRecord::ConnectionAdapters::ConnectionHandler
      def initialize
        super
        @pools_by_subdomain = {}
      end
    
      # Override the behaviour of ActiveRecord's ConnectionHandler to return a
      # connection pool for the current domain.
      def retrieve_connection_pool(klass)
        # Get current subdomain somehow (Maybe store it in a class variable on 
        # each request or whatever)
        subdomain = @@subdomain
        @pools_by_subdomain[subdomain] ||= create_pool(subdomain)
      end
    
      private
      def create_pool(subdomain)
        conf = Rails.configuration.database_configuration[Rails.env].dup
        # The name of the DB for that subdomain...
        conf.update!('database' => "db_#{subdomain}")
        resolver = ActiveRecord::Base::ConnectionSpecification::Resolver.new(conf, nil)
        # Call ConnectionHandler#establish_connection, which receives a key 
        # (in this case the subdomain) for the new connection pool
        establish_connection(subdomain, resolver.spec)
      end
    end
    
[/code]

元記事ではサブドメインに応じてコネクションを変えるという要件になっていて、`retrieve_connection_pool`メソッドの中でコネクションを切り替えています。

このあたりをご自身の要件に合うように変更すれば、目的が達成できるかもしれません。

以上、ご参考までに。


CC BY-SA 3.0
2015-03-11T11:55:10.667
7794
2015-03-11T11:55:10.667
2017-05-23T12:38:56.083
-1
85
7779
answer