PostgreSQL查询以检查一行是否被多个表引用

4
我有一个主表A,还有两个不同的子表(B,C),这些子表通过外键引用到表A中。我想检查B或C表是否存在具有外键fk-1的行。
我尝试从A表中选择使用fk-1选择的B和C表,并使用exists子句检查它们的行是否存在,然后将结果进行逻辑或操作。
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)
);

这个能优化吗,或者有更好的方法来处理吗。

提前感谢。


4
我认为没有更有效(或更简单)的方法。 - user330315
你好,当在exists子句中需要添加更多的表时,多次使用OR会对性能产生什么影响? - Archit
1个回答

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的记录。

1
列已经被索引,这是为了进行单个检查。感谢您指出如何检查它们的一堆方法。 - Archit
一个常见的陷阱是为每一行你想要检查的数据都调用这个SQL语句。错误的。(你从哪里学来的?) - wildplasser
这取决于实际的SQL和如何规划,但通常情况下是正确的: 对许多项扫描B-Tree索引所需的时间要比每次重新开始扫描要少得多。而且,不要忘记,对于每个SQL,您都必须支付往返、解析时间和计划时间的惩罚。因此,除非1行版本的计划比许多行版本好得多,否则许多行版本更快(在我的经验中,这种情况占到了95%的时间)。 - deavidsedice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接