Class: FastCount::Adapters::MysqlAdapter

Inherits:
BaseAdapter show all
Defined in:
lib/fast_count/adapters/mysql_adapter.rb

Instance Method Summary collapse

Methods inherited from BaseAdapter

#initialize, #install, #uninstall

Constructor Details

This class inherits a constructor from FastCount::Adapters::BaseAdapter

Instance Method Details

#estimated_count(sql) ⇒ Object

Tree format was added in MySQL 8.0.16. For other formats I wasn’t able to find an easy way to get this count.



20
21
22
23
# File 'lib/fast_count/adapters/mysql_adapter.rb', line 20

def estimated_count(sql)
  query_plan = @connection.select_value("EXPLAIN format=tree #{sql}")
  query_plan.match(/rows=(\d+)/)[1].to_i
end

#fast_count(table_name, threshold) ⇒ Object

Documentation says, that this value may vary from the actual value by as much as 40% to 50%.



9
10
11
12
13
14
15
16
# File 'lib/fast_count/adapters/mysql_adapter.rb', line 9

def fast_count(table_name, threshold)
  estimate = @connection.select_one("SHOW TABLE STATUS LIKE #{@connection.quote(table_name)}")["Rows"]
  if estimate >= threshold
    estimate
  else
    @connection.select_value("SELECT COUNT(*) FROM #{@connection.quote_table_name(table_name)}")
  end
end

#fast_distinct_count(table_name, column_name) ⇒ Object

MySQL already supports “Loose Index Scan” (see dev.mysql.com/doc/refman/8.0/en/group-by-optimization.html), so we can just directly run the query.



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/fast_count/adapters/mysql_adapter.rb', line 27

def fast_distinct_count(table_name, column_name)
  unless index_exists?(table_name, column_name)
    raise "Index starting with '#{column_name}' must exist on '#{table_name}' table"
  end

  @connection.select_value("    SELECT COUNT(*) FROM (\n      SELECT DISTINCT \#{@connection.quote_column_name(column_name)} FROM \#{@connection.quote_table_name(table_name)}\n    ) AS tmp\n  SQL\nend\n")