【问题标题】:Rails extremely slow database queryingRails 数据库查询速度极慢
【发布时间】:2016-08-09 09:44:17
【问题描述】:

我的应用程序当前有一个表,其中包含大约 1280 万行,并且该表与另外 5 个表具有 has_one 关联,其中每个表具有相同的 1280 万行。

然后,所有这些数据都将显示在具有过滤功能的表格中,使用 filterrific gem。问题是执行特定列搜索之类的查询需要花费太多时间,而 Table.count 查询大约需要 30-40 秒才能完成。有没有可以大大减少查询时间的查询优化方法?

我已尝试实现预加载并选择仅显示所需的列,但性能提升并不显着。

示例架构:

domain.rb

create_table "domains", force: :cascade do |t|
    t.string   "name",                                     null: false
    t.integer  "age",                      default: 0
    t.integer  "pr",                       default: 0
    t.boolean  "dmoz",                     default: false
    t.float    "price",                    default: 0.0
    t.string   "listing_type"
    t.datetime "created_at",                               null: false
    t.datetime "updated_at",                               null: false
    t.string   "source"
    t.datetime "end_date_time"
    t.integer  "no_bids",                  default: 0
    t.float    "traffic",                  default: 0.0
    t.float    "valuation",                default: 0.0
  end
add_index "domains", ["name"], name: "index_domains_on_name", unique: true, using: :btree

对于搜索过滤器,使用范围和下面的示例:

  scope :basic, lambda { |basic|
    query = ""
    query += "age BETWEEN #{check_min(basic.age_min.to_i)} AND #{check_max(basic.age_max.to_i)} " if basic.age_min.present? || basic.age_max.present?
    query += "AND price BETWEEN #{check_min(basic.price_min.to_f)} AND #{check_max(basic.price_max.to_f)} " if basic.price_min.present? || basic.price_max.present?
    query += "AND pr BETWEEN #{check_min(basic.pr_min.to_i)} AND #{check_max(basic.pr_max.to_i)} " if basic.pr_min.present? || basic.pr_max.present?
    if query[0..2] == 'AND'
      query = query[3..-1]
    end

    where(query)
  }

【问题讨论】:

  • 您能否提供有关您的架构以及如何搜索架构的更多信息?听起来您需要更多/更好的索引,但如果没有更多细节,很难说什么会加快速度。
  • 您要优化的是计数还是查询?给定表的大小,一个近似值是否足以计数?
  • 大家好,我刚刚添加了一些额外的细节。如果可能的话,我想加快计数和查询速度。 @ChrisTravers 如果能显着减少时间,一个近似值就足够了。顺便问下大概的值怎么弄?

标签: ruby-on-rails database postgresql


【解决方案1】:

要获得近似的行数,请在 SQL 中执行以下操作

SELECT reltuples AS approximate_row_count 
  FROM pg_class WHERE relname = 'domains';

现在您还没有提供生成的 SQL 或查询计划,所以这里有一些一般性的建议可以帮助您继续前进。随着更多信息的出现,我可能会添加一些更具体的建议,但这有点有限。

SQL 是一种声明性语言,这意味着我们告诉数据库我们想要什么,并尝试确保它能够快速完成。所以你要做的是记录慢语句(log_min_duration_statement 在你的 postgresql.conf 中),然后解释分析这些语句。如果没有查询计划,就很难看出可能需要哪些索引。

查询计划基本上告诉你 PostgreSQL 决定,给定可用的索引,是检索你想要的数据的最快方法。如果您意外地对大型表进行顺序扫描,您希望从那里查看选择性标准(即删除最多行的方法)并索引这些字段(顺序扫描通常更快,但是,当您检索大约 10% 时表)。

【讨论】:

    猜你喜欢
    • 2016-02-29
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2018-04-17
    相关资源
    最近更新 更多