Search code examples
ruby-on-railsrubyactiverecordsequelmysql2

Rails ActiveRecord mysql2 adapter, use PreparedStatement by default


PreparedStatement support for mysql2 has been already added in version 0.4.0, as per this link
As per following details in version 0.5.2 it still not uses prepared statement in all ORM queries internally:

Shipment.where(order_id: 78987898789)<br>
Shipment.where('order_id = ?', 56789876)

Mysql Log:

2019-03-10T13:20:01.722848Z  1072 Query SELECT `shipments`.* FROM `shipments` WHERE `shipments`.`order_id` = 78987898789<br>
2019-03-10T13:22:27.748687Z  1072 Query SELECT `shipments`.* FROM `shipments` WHERE (order_id = 56789876)

Is there a way to enable/disable it for all ORM queries? (Just like the PostgreSQL adapter ref). Does enabling it impact adversely on overall application performance?

If not, I haven't given a try yet but is it possible to achieve this using Sequel, and how complex is migrating an existing application from MySQL2 to Sequel.


Solution

  • ActiveRecord with Mysql2 < 5, doesn't support configurable parameter to enable prepared_statement
    Code snippet from ActiveRecord 4.2.6

    connection_adapters/mysql2_adapter.rb

    module ConnectionAdapters
    class Mysql2Adapter < AbstractMysqlAdapter
      ADAPTER_NAME = 'Mysql2'.freeze
    
      def initialize(connection, logger, connection_options, config)
        super
        @prepared_statements = false # No configurable param, default set to false
        configure_connection
      end
      ...
    end
    

    ActiveRecord with Mysql2 = 5.2.1 adapter support configurable parameter to enable prepared_statement Code snippet from ActiveRecord 5.2.1

    connection_adapters/mysql2_adapter.rb

    module ConnectionAdapters
    class Mysql2Adapter < AbstractMysqlAdapter
      ADAPTER_NAME = "Mysql2".freeze
    
      include MySQL::DatabaseStatements
    
      def initialize(connection, logger, connection_options, config)
        super
        @prepared_statements = false unless config.key?(:prepared_statements)
        configure_connection
      end
      ...
    end
    

    So, in ActiveRecord 5.2.1, one can just add following line in database.yml to enable prepared_statements

    prepared_statements: true