2017-03-07 46 views
0

我有这样的说法:性能问题声明

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秒

谁能给我解释一下为什么是这样的情况。 ?我不明白..

+0

尝试使用'explain'运行两者 - 我猜临时表的连接速度比in子句的扫描速度快很多 – paqash

+0

您使用的是哪个版本的rom-rb? – solnic

+0

@solnic rom3.1.0,rom-repository 1.2.0和rom-sql 1.1.1但是来自karthik的回答对我来说足够了。谢谢! – Shimu

回答

2

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

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

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