lib/wt_activerecord_index_spy/query_analyser.rb
# The sql and binds vary depend on the adapter.
# - Mysql2: sends sql complete and binds = []
# - Postregs: sends sql in a form of prepared statement and its values in binds
# rubocop:disable Metrics/MethodLength
The sql and binds vary depend on the adapter.
Mysql2: sends sql complete and binds = []
Postregs: sends sql in a form of prepared statement and its values in binds
rubocop:disable Metrics/MethodLength
The sql and binds vary depend on the adapter . Mysql2 : sends sql complete and binds = [] Postregs : sends sql in a form of prepared statement and its values in binds rubocop : disable Metrics / MethodLength
def analyse(sql:, connection: ActiveRecord::Base.connection, binds: [])
      query = sql
      return @analysed_queries[query] if @analysed_queries.key?(query)
      adapter = select_adapter(connection)
      Thread.new do
        results = ActiveRecord::Base.connection_pool.with_connection do |conn|
          conn.exec_query("EXPLAIN #{query}", "SQL", binds)
        end
        adapter.analyse(results).tap do |certainity_level|
          @analysed_queries[query] = certainity_level
        end
      end.join.value
    end
def analyse ( sql : , connection : ActiveRecord :: Base . connection , binds : [ ] ) query = sql return @analysed_queries [ query ] if @analysed_queries . key? ( query ) adapter = select_adapter ( connection ) Thread . new do results = ActiveRecord :: Base . connection_pool . with_connection do | conn | conn . exec_query ( "EXPLAIN #{query}" , "SQL" , binds ) end adapter . analyse ( results ) . tap do | certainity_level | @analysed_queries [ query ] = certainity_level end end . join . value end
The sql and binds vary depend on the adapter.
The sql and binds vary depend on the adapter .
# TODO: this could be more intelligent to not duplicate similar queries # with different WHERE values, example: # - WHERE lala = 1 AND popo = 1 # - WHERE lala = 2 AND popo = 2 # Notes: # - The Postgres adapter uses prepared statements as default, so it # will save the queries without the values. # - The Mysql2 adapter does not use prepared statements as default, so it # will analyse very similar queries as described above. # We need a thread to use a different connection that it's used by the # application otherwise, it can change some ActiveRecord internal state # such as number_of_affected_rows that is returned by the method # `update_all`
sql
<not_specific>
connection
<not_specific>
binds
<not_specific>