我有两个问题。第一个使用 select 中的子查询从一个列中检索一些聚合作为列,(返回所有行的列的字符串连接)。
第二个查询通过在 中进行子选择然后加入结果来做同样的事情。然而,第二个查询在加入之前在整个表上进行聚合,但速度要快得多(286ms vs 7645ms)。
我不明白为什么子查询这么慢,而第二个查询在一个有175k行的表上进行聚合(在postgresql 9.5上)。使用子选择更容易集成到查询构建器中,因此我想使用它,第二个查询将在记录数增加时减慢。有没有办法提高子选择的速度?
查询1:
select kp_No,
(select string_agg(description,E'\n') from (select nt_Text as description from fgeNote where nt_kp_No=fgeContact.kp_No order by nt_No DESC limit 3) as subquery) as description
from fgeContact
where kp_k_No=729;
解释:https://explain.depesz.com/s/8sL
查询2:
select kp_No, NoteSummary
from fgeContact
LEFT JOIN
(select nt_kp_No, string_agg(nt_Text,E'\n') as NoteSummary
from
(select nt_kp_No, nt_Text from fgeNote ORDER BY nt_No DESC) as sortquery
group by nt_kp_No) as joinquery
ON joinquery.nt_kp_No=kp_No
where kp_k_No=729;
答案 0 :(得分:0)
这是因为在第二个查询中,您在第一个查询中检索所有寄存器,而在第一个查询中,子查询每个主表的每个选定寄存器执行一次,因此,每次应该再次扫描该表
即使使用索引扫描,它通常比扫描整个表更昂贵,甚至是顺序扫描(实际上,当选择多个寄存器时,顺序扫描比索引扫描快得多,因为索引意味着一些开销)并且仅选择有趣的寄存器。
但这也取决于实际的数据分布。完全可能的是,对于 kp_k_No 的不同值,如果表只包含一个或几个具有该参数值的行,则第二个查询会变得更快。
这是一个测试问题,并猜测会发生的不同情况......