diff options
author | Nick Thomas <nick@gitlab.com> | 2019-03-12 17:16:27 +0000 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2019-03-12 17:16:27 +0000 |
commit | 24f2dcd1cb33652ea4f1b230576e599ae4ed7f8f (patch) | |
tree | 7dbff33911baa6d7e5ebc00ccf7e08122d3ed265 /lib | |
parent | ccbbc1000d12da078a6fd1e88d8c215673e202d6 (diff) | |
parent | b35a6880b90df6bc97a806f053abeb579ebec62f (diff) | |
download | gitlab-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.rb | 18 | ||||
-rw-r--r-- | lib/gitlab/database/count/tablesample_count_strategy.rb | 10 |
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) |