【问题标题】:Large database query: optimisation大型数据库查询:优化
【发布时间】:2018-02-06 14:40:35
【问题描述】:

我有一个Product 模型,具有description 属性。 创建新产品时,我需要在描述中查找具有相应引用的产品,并在它们之间创建一个Link 对象。

例子:

Product 1
Description: ".... 58274072 ... "

我需要查找描述中包含58274072 的所有产品:

similar_products = Product.where("description like ?", "%58274072%")

我有两个问题:

  • 鉴于我们拥有大量产品记录,此查询可能需要几秒钟才能运行。有没有更快的查询方法?
  • 我在批处理作业中运行此查询,因此可能有 10 多个作业同时运行并尝试执行此查询。单独对一个查询进行基准测试时,假设运行需要 2 秒。批量运行时,最多需要 6 秒。这会是由于数据库连接数太低造成的吗?

我该如何解决这些问题?

【问题讨论】:

  • 在我看来,这更像是一个数据库问题,而不是前端问题。如果我经常执行这样的查询,我会考虑在后端支持,例如使用全文索引、tsvector、引用关键字作为数组索引等,具体取决于您使用的数据库。
  • @CetinBasoz 我没有把它标记为前端
  • @GrahamSlick 您标记了 ruby​​-on-rails,但没有标记您的 SQL 平台
  • 不要在like 模式中使用通配符。无论您在表上拥有任何索引或分区,这些都会强制进行全表扫描。
  • 啊,现在标记为 postgresql。然后我会研究 tsvector,tsquery(可以被索引)。或者有另一个可以被索引的“搜索关键字”数组字段。

标签: sql ruby-on-rails database postgresql activerecord


【解决方案1】:

要优化 LIKE 上的索引,您应该使用 trigam 扩展。

为此,您需要安装模块 pg_trgm,它为 GIN 和 GiST trigram 索引提供运算符类以支持所有 LIKE 和 ILIKE 模式:

示例索引:

CREATE INDEX ON product USING gin (description gin_trgm_ops);

或:

CREATE INDEX ON product USING gist (description gist_trgm_ops);

您需要在 GIN 或 GiST 之间进行选择...GIN 的查询速度更快,但创建速度较慢,更新速度较慢,而且通常比 GiST 大。

如果它解决了你的问题,试试这个。

【讨论】:

    【解决方案2】:

    我建议不要使用like,而是创建具有2列的表product_references:product_idreference(此列可以被索引)。一个产品可以有多个引用,因此它将有多个 product_references 行。那么流程应该改变如下:

    • 创建产品时,解析该产品描述中的引用并在 product_references 表中搜索类似产品
    • 创建Link 对象作为您的业务规则
    • 为新产品创建新的 product_reference 行

    解析、搜索、链接和创建新product_reference的步骤可以由后台作业处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-15
      • 2013-08-09
      • 1970-01-01
      • 2020-08-11
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多