summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2019-03-12 17:16:27 +0000
committerNick Thomas <nick@gitlab.com>2019-03-12 17:16:27 +0000
commit24f2dcd1cb33652ea4f1b230576e599ae4ed7f8f (patch)
tree7dbff33911baa6d7e5ebc00ccf7e08122d3ed265 /lib
parentccbbc1000d12da078a6fd1e88d8c215673e202d6 (diff)
parentb35a6880b90df6bc97a806f053abeb579ebec62f (diff)
downloadgitlab-ce-24f2dcd1cb33652ea4f1b230576e599ae4ed7f8f.tar.gz
Merge branch 'sh-skip-sti-tables-reltuples' into 'master'
Fix counting of groups in admin dashboard Closes gitlab-ee#7435 See merge request gitlab-org/gitlab-ce!26009
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/database/count/reltuples_count_strategy.rb18
-rw-r--r--lib/gitlab/database/count/tablesample_count_strategy.rb10
2 files changed, 26 insertions, 2 deletions
diff --git a/lib/gitlab/database/count/reltuples_count_strategy.rb b/lib/gitlab/database/count/reltuples_count_strategy.rb
index c3a674aeb7e..695f6fa766e 100644
--- a/lib/gitlab/database/count/reltuples_count_strategy.rb
+++ b/lib/gitlab/database/count/reltuples_count_strategy.rb
@@ -37,6 +37,22 @@ module Gitlab
private
+ # Models using single-type inheritance (STI) don't work with
+ # reltuple count estimates. We just have to ignore them and
+ # use another strategy to compute them.
+ def non_sti_models
+ models.reject { |model| sti_model?(model) }
+ end
+
+ def non_sti_table_names
+ non_sti_models.map(&:table_name)
+ end
+
+ def sti_model?(model)
+ model.column_names.include?(model.inheritance_column) &&
+ model.base_class != model
+ end
+
def table_names
models.map(&:table_name)
end
@@ -47,7 +63,7 @@ module Gitlab
# Querying tuple stats only works on the primary. Due to load balancing, the
# easiest way to do this is to start a transaction.
ActiveRecord::Base.transaction do
- get_statistics(table_names, check_statistics: check_statistics).each_with_object({}) do |row, data|
+ get_statistics(non_sti_table_names, check_statistics: check_statistics).each_with_object({}) do |row, data|
model = table_to_model[row.table_name]
data[model] = row.estimate
end
diff --git a/lib/gitlab/database/count/tablesample_count_strategy.rb b/lib/gitlab/database/count/tablesample_count_strategy.rb
index fedf6ca4fe1..4fcd68b297d 100644
--- a/lib/gitlab/database/count/tablesample_count_strategy.rb
+++ b/lib/gitlab/database/count/tablesample_count_strategy.rb
@@ -48,12 +48,20 @@ module Gitlab
end
end
+ def where_clause(model)
+ return unless sti_model?(model)
+
+ "WHERE #{model.inheritance_column} = '#{model.name}'"
+ end
+
def tablesample_count(model, estimate)
portion = (TABLESAMPLE_ROW_TARGET.to_f / estimate).round(4)
inverse = 1 / portion
query = <<~SQL
SELECT (COUNT(*)*#{inverse})::integer AS count
- FROM #{model.table_name} TABLESAMPLE SYSTEM (#{portion * 100})
+ FROM #{model.table_name}
+ TABLESAMPLE SYSTEM (#{portion * 100})
+ #{where_clause(model)}
SQL
rows = ActiveRecord::Base.connection.select_all(query)