Sql 用其他东西替换左联接系列?

Sql 用其他东西替换左联接系列?,sql,postgresql,Sql,Postgresql,我有个人、公司和员工。这些表中的每一个都有一个外键返回到我调用的表,该表通过触发器维护同级记录。缔约方有0到N个site_定位器,其本身引用的是site,而site_定位器引用的是城市 我正在构建一个视图,该视图将返回收件人的全名和所在城市。因此,现行守则是: SELECT surname , rest_of_name , 'Employee' AS party_type_code , party_id , cities.name AS city

我有个人、公司和员工。这些表中的每一个都有一个外键返回到我调用的表,该表通过触发器维护同级记录。缔约方有0到N个site_定位器,其本身引用的是site,而site_定位器引用的是城市

我正在构建一个视图,该视图将返回收件人的全名和所在城市。因此,现行守则是:

  SELECT
      surname
    , rest_of_name
    , 'Employee'  AS party_type_code
    , party_id
    , cities.name AS city_name
  FROM
              employees
    LEFT JOIN site_locators USING (party_id)
    LEFT JOIN sites         USING (site_id)
    LEFT JOIN cities        USING (city_id)
UNION ALL
  SELECT
      surname
    , NULL::text
    , 'Company'  AS party_type_code
    , party_id
    , cities.name AS city_name
  FROM
              companies
    LEFT JOIN site_locators USING (party_id)
    LEFT JOIN sites         USING (site_id)
    LEFT JOIN cities        USING (city_id)
UNION ALL
  SELECT
      surname
    , rest_of_name
    , 'Person'  AS party_type_code
    , party_id
    , cities.name AS city_name
  FROM
              people
    LEFT JOIN site_locators USING (party_id)
    LEFT JOIN sites         USING (site_id)
    LEFT JOIN cities        USING (city_id)
我真的不喜欢每个联合上的多个左联合。我对代码进行了重构,以作为一个单独的步骤只执行一次连接:

SELECT
    parties.*
  , cities.name AS city_name
FROM (
    SELECT /* As above, minus city_name */
    FROM employees
  UNION ALL
    SELECT /* As above, minus city_name */
    FROM companies
  UNION ALL
    SELECT /* As above, minus city_name */
    FROM people
  ) AS parties
  LEFT JOIN site_locators USING (party_id)
  LEFT JOIN sites         USING (site_id)
  LEFT JOIN cities        USING (city_id)
第二个查询速度更快,因为联接只在筛选所有表之后发生一次。我想知道的是,我是否可以进一步重构它,这样,如果site_定位器没有返回派对的行,那么我甚至不需要搜索站点或城市?我想知道这是否可以用一些内部连接而不是所有的左连接重写。我以前在左连接方面有过不好的经验,希望减少它们的数量


注意:parties表的存在是为了减少表的数量。如果它不存在,我需要每种派对类型和定位器类型的表格:员工站点定位器、人员站点定位器、公司站点定位器、员工电子邮件定位器、人员电子邮件定位器等等。使用parties表,我可以为每个定位器类型创建一个*_定位器表。

首先,第一次重构非常好

其次,是左联接约束规划器。但是,如果将这些连接块分为内部连接块和外部连接块,则会在更多方面限制规划器,这些是更大的限制。总的来说,我看到规划人员在按照您描述的方式分解左连接时,使用索引的能力有所下降


一般来说,最好先关注清晰度,然后再考虑调整以获得更好的性能,而不是先担心性能,然后再关注清晰度。不过,有一件事会有所帮助,那就是用启用的
替换
最后看看您的模型,看看什么是真正的左连接,什么是内部连接。请注意,这些连接非常不同,因此不能直接替换。

如果您需要您的行在所有列出的表中始终显示数据,将
左连接更改为
内连接将实现这一点,并且还应限制搜索范围。您应该(可能)能够让查询保持原样,因为大多数现代优化器不管怎样都会弄乱连接顺序。我理解左连接和内连接之间的区别。city_name列中的数据是可选的:如果存在,我需要它。如果它不存在,也没关系,因此我使用了LEFT-JOIN。好吧,对不起,这并不是您要求的一部分(或者至少,我没有在其中读到)。在这种情况下,左连接可能是最好的连接;除非某些后续联接可以使用内部联接重新写入。但是,在不知道表结构和所需结果的情况下,很难准确判断以这种方式可以更改哪些内容。这对连接没有帮助,但这看起来像是PG的表继承功能可能会导致混乱的情况。
各方
员工
人员
公司
之间的关系看起来像是在动态创建继承结构。您认为
上的
使用
更清晰吗<代码>使用
可以减少总字数,在我看来,这会让阅读变得更容易。如何在
上增加清晰度?