一个非常大的IN(ids)语句的性能问题

时间:2017-03-07 13:31:01

标签: sql ruby postgresql sequel rom-rb

我有这样的声明:

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秒内得到结果。

有人可以向我解释为什么会这样吗?我不明白..

1 个答案:

答案 0 :(得分:3)

当你使用IN子句时,特别是有很多值时,数据库别无选择,只能迭代地将每个元组值与IN子句中的每个值进行比较,这样效率很低。

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

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