【问题标题】:PostgreSQL query to check if a row is referenced from multiple tablesPostgreSQL查询检查是否从多个表中引用了一行
【发布时间】:2019-07-10 08:07:00
【问题描述】:

我有一个主表A,和两个不同的子表(B,C),由表A中的外键引用,我想检查表B或C中是否存在带有外键fk-1的行。

我尝试通过在 B 和 C 上使用存在子句从 A 中选择行,这些行是使用 fk-1 进一步 OR'ed 一起选择的,并找到了结果。

SELECT A.id FROM A where A.id = fk-1 AND
(
    EXISTS (select B.id from B where B.fk_1 = fk-1)
    OR EXISTS (select C.id from C where C.fk_1 = fk-1)
);

这可以优化还是有更好的方法来做到这一点。

提前致谢。

【问题讨论】:

  • 我认为没有更有效(或更简单)的方法。
  • 您好,当exists子句中需要添加更多表时,多次使用OR对性能有什么影响?

标签: sql postgresql query-performance


【解决方案1】:

对于给定 A.id、B.fk_1 和 C.fk_1 索引的情况下最快的单次检查

一个常见的陷阱是为您可能要检查的每一行调用此 SQL。如果一次检查所有行,检查速度会更快。 (每行检查速度更快)

所以如果你想同时检查一堆,你可以这样做:

SELECT A.id FROM A WHERE A.id IN (
    SELECT B.fk_1 FROM B [WHERE xxx] 
    UNION SELECT C.fk_1 FROM C [WHERE xxx])

使用 [WHERE xxx] 放置 WHERE 以过滤您可能想要的相关结果。 一项推荐的检查是“WHERE B.fk_1 IS NOT NULL”以过滤掉没有 FK 的记录。

【讨论】:

  • 列被索引,用于单次检查。感谢您提供有关如何检查其中一堆的指针。
  • A common pitfall is calling this SQL for every single row you might want to check. 错误。 (你从哪里学来的?)
  • 这取决于实际的 SQL 及其计划方式,但对于一般情况,情况确实如此:扫描 B-Tree 索引的许多项目所需的时间比每次开始扫描所需的时间要少得多。而且,不要忘记,对于每个 SQL,您都必须为往返、解析时间和计划时间付出代价。因此,除非 1 行版本比多行版本有更好的计划,否则多行版本会更快(根据我的经验是 95% 的时间)。
猜你喜欢
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 2020-08-11
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
相关资源
最近更新 更多