查询行对应于另一个表中的多行数据的最佳方法

时间:2018-03-30 05:51:25

标签: sql database postgresql

所以我有两个表,AB

A有一个主键id

B实际上是A中条目的列表。因此B具有外键id,但每个id可能有多行。

我想运行一个查询,获取一行A以及B中的所有相应行。

现在我正在使用INNER JOIN执行此操作,但我关注性能 - A中的条目在输出中的每一行上都是重复的,以便与{{1}对应}。

以下是一个例子:

B

A id | blah 1 | x 2 | y

另请注意,B id | foo 1 | m 1 | n 1 | o 2 | p 可能包含许多包含相关数据的列,而不只是一列B列。

我希望能够运行fooSELECTid = 1来自blah = xAfoo = m来自foo = n的{​​}和foo = o。但是除非我过度思考它,否则似乎返回以下内容的连接效率会非常低,因为B可能会非常大,反复重复(这也有点难以解析)服务器端)。

x

我觉得这是一个足够普遍的程序,它应该有一个有效的查询,但我无法清楚地得到足够的措辞,以便在网上找到任何有用的东西:(

我正在使用PostgreSQL 10,但我想这个命令可能与其他查询语言类似。

1 个答案:

答案 0 :(得分:3)

我怀疑担心加入结果中的冗余数据量是不必要的,除非您有证据表明客户端上的网络带宽或解析值是您的瓶颈。

通常,返回所有结果的单个查询(下面的选项1)最好。

你应该运行一个基准测试并比较这两件事:

  1. 简单查询:

    SELECT id, a.blah, b.foo
    FROM a JOIN b USING (id);
    
  2. 两个查询,避免了结果冗余:

    SELECT a.id, a.blah
    FROM a
    WHERE EXISTS
       (SELECT 1 FROM b
        WHERE b.id = a.id);
    
    SELECT id, b.foo
    FROM a JOIN b USING (id);
    
  3. 所有其他方法必须更慢:

    • 通过对ba中找到的每一行IN执行单独查询,在应用程序中执行嵌套循环连接是疯狂的。它总是会表现更差,因为必须为连接结果中的每一行支付执行数据库查询(组成查询,发送,解析和处理数据库,发回结果,解析结果)的开销。

    • 使用第一个查询中找到的iduser列表发送第二个查询可能会生成需要很长时间才能解析的非常长的语句。此外,这些语句的执行效率低于连接本身。从本质上讲,它是散列连接的去优化版本。

相关问题