Select Psql-from子句中的子查询-错误实践?

Select Psql-from子句中的子查询-错误实践?,select,count,psql,union-all,Select,Count,Psql,Union All,手头的任务是选择音乐家(pid)和每次演奏的乐器数量,包括仅在音乐会上演奏的乐器-这些乐器可能不在[演奏]表中 我已经解决了这个问题,但是我读到,如果可能的话,应该避免from子句中的子查询。只是出于好奇,有谁能告诉我一个更有效的方法吗?或者这是一个好的解决方案?我正在使用psql select a.pid, sum(a.instr) from ( select pid, count(instr) as instr from plays group by pid union a

手头的任务是选择音乐家(pid)和每次演奏的乐器数量,包括仅在音乐会上演奏的乐器-这些乐器可能不在[演奏]表中

我已经解决了这个问题,但是我读到,如果可能的话,应该避免from子句中的子查询。只是出于好奇,有谁能告诉我一个更有效的方法吗?或者这是一个好的解决方案?我正在使用psql

select a.pid, sum(a.instr)
from 
(
    select pid, count(instr) as instr from plays group by pid
    union all
    select pid, count(instr) as instr from concert group by pid
) as a
group by a.pid;

这样的疑问不是问题。数据库的查询优化器将负责从该查询中获得最佳效果。在某些情况下,
内部联接
将转换为与子
选择
完全相同的执行计划

如果您认为查询有问题,可以随时启动psql的函数。这将为您提供查询实际执行情况的概述。通过这种方式,您还可以比较编写查询的不同方式


你举的例子。。。我不认为没有子查询就可以很容易地解决这个问题。我认为你选择的方式很好。任何涉及一些左连接的内容都将更难阅读。

优点

  • 子查询是有利的,因为它们构造查询以隔离语句的每个部分,执行通常需要复杂联接和联合的相同操作,并且更易于阅读
缺点

  • 使用子查询时,查询优化器可能需要执行额外的步骤,以便执行这些步骤所需的时间比连接所需的时间更长

  • 对父查询的每一行执行一次不相关子查询。如果这类子查询处理大量数据,则处理数据需要很长时间

可能的解决方案:

  • 您可以创建临时表来存储子查询的数据,然后使用联接来完成查询。请记住,使用联接比使用子查询要好

  • 使用with子句
    WITH
    提供了一种编写辅助语句的方法,以便在更大的查询中使用。这些语句通常被称为公共表表达式或CTE,可以被视为定义只存在于一个查询中的临时表。它允许您只执行一次子查询,而不是对每行执行一次


注意:您应该避免使用UNION或UNION ALL。

您的缺点是不正确的。外部查询中的每行执行一次相关子查询,但不执行不相关子查询。临时表通常比较慢,而且不必要,因为您可能会使用CTE,这也会由于优化程序的限制而出现问题。这真的不准确。优势部分也不正确,因为优化器可以上拉、下推和展平子查询。更具体地说,查询计划器可以而且经常会展平子查询,将条件从子查询上拉到外部查询,将条件从外部查询下推到子查询,子查询大多只是符号化的,与查询的实际执行方式没有预期的那么多关系。至少在PostgreSQL中是这样。