【问题标题】:Performance issue with a really big IN (ids) statement非常大的 IN (ids) 语句的性能问题
【发布时间】:2017-07-27 17:45:31
【问题描述】:

我有这样的声明:

select qulified_name
from table
inner join references_table on references_table.id = table.ref_id
where references_table.type = 'x' and table.value in (... +110 000 ids)

这非常慢。 (网络应用程序崩溃并且没有得到结果。 我在 rom-rb 的帮助下创建了我的声明,这使用了续集。但这是我看到声明时得到的声明。

如果我像这样重写语句,与第一个版本相比,性能真的很好:

select qulified_name
from table
inner join (select unnest(array['#{references_id.join("','")}']) id ) as tmp on tmp.id = businesspartner_references.value
inner join references_table on references_table.id = table.ref_id
where references_table.type = 'x'

这样我可以在大约 3 秒内得到结果。

有人可以向我解释为什么会这样吗?没看懂。。

【问题讨论】:

  • 尝试同时运行 explain - 我猜连接到临时表比扫描 in 子句要快很多
  • 您使用的是哪个版本的 rom-rb?
  • @solnic rom3.1.0, rom-repository 1.2.0 和 rom-sql 1.1.1 但是 karthik 的回答对我来说已经足够解释了。谢谢!
  • 我会在 rom-sql 2.0 (FWIW) 中优化这种类型的查询

标签: sql ruby postgresql sequel rom-rb


【解决方案1】:

当您使用 IN 子句时,尤其是包含大量值时,数据库别无选择,只能迭代地比较每个元组值与 IN 子句中的每个值,这将是低效的。

相反,当您使用子查询将其转换为派生表时,它现在会转换为面向集合的连接操作。

数据库非常擅长评估面向集合的操作,并且可以为您的数据找到最佳的连接算法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 2015-02-25
    • 2020-05-10
    相关资源
    最近更新 更多