在PostgreSQL中执行2个查询和1个大查询哪个更好?

lf5gs5x2  于 2022-10-15  发布在  PostgreSQL
关注(0)|答案(2)|浏览(215)

我正在研究一个权利验证系统。为了验证用户是否有权访问文档,我向数据库提出了一个请求,在两种情况下可以获得访问权限:
1.用户在此文档的访问区域中(例如,在发布文档的聊天中的用户)

select count(*) > 0 from Document 
   left join Chat
   left join ChatUser
   left join User
   left join Resource
   ...
where ...

1.文件是公开的

select count(*) > 0 from Document 
   left join User
   left join Resource
   left join ...
   ...
where ...

我看到了两种解决方案
1.提出涵盖两种情况的请求(工会)
此类解决方案的优点->向数据库发出1个请求
这种解决方案的缺点->在70%的情况下,我每次都会进行额外的5个连接,这会影响数据库中的查询性能
1.提出2个请求
首先请求该文档是否在聊天中。
如果为假->则再提出1个请求

告诉我在这种情况下使用的是什么算法?

a1o7rhls

a1o7rhls1#

如果您有一对一的关系,那么应该使用联接查询。
具有一对多关系的连接查询会导致具有冗余数据的更多内存使用。
如果您没有内存使用问题,那么您还应该使用联接查询,因为在大多数情况下,联接查询比多个查询更快。

t30tvxxf

t30tvxxf2#

如果您认为网络延迟会破坏交易,为什么不在plsql函数中卸载‘如果第一次找不到,请尝试第二次查询’?您只需查询该函数一次,它就会返回一个布尔值。见鬼,你可以很容易地添加另一个标志,表明它是否在聊天中发现了它,或者如果你的应用程序需要这些信息,它也需要查看公共信息。
也就是说,通过重写查询,您可能可以获得相当大的性能

select count(*) > 0 from Document 
   left join Chat
   left join ChatUser
   left join User
   left join Resource
   ...
where ...

SELECT (CASE WHEN EXISTS (
                            select * from Document 
                               left join Chat
                               left join ChatUser
                               left join User
                               left join Resource
                               ...
                            where ... ) THEN True ELSE False END)

这样,系统不需要检查所有适用的情况,但可以在第一场比赛时停止。
我也觉得奇怪,你在里面有LEFT OUTER JOIN s,而不是INNER JOIN s,但这可能是把它放在StackOverflow上的简化,对吗?
我实际上在想,仅仅使用WHERE EXISTS()合并这两个查询是否会让优化器执行“只有在第一个没有找到的情况下才执行第二部分”的操作……EXPLAIN ANALYZE应该很清楚地表明了这一点。使用https://explain.dalibo.com/或类似的东西来使其更容易解释。
因此,它将变成这样:

SELECT (CASE WHEN EXISTS (
                            select * from Document 
                              join Chat
                              join ChatUser
                              join User
                              join Resource
                               ...
                            where ... ) 
               OR EXISTS (              

                            select * from Document 
                              join User
                              join Resource
                              join ...
                               ...
                            where ...   )

            THEN True ELSE False END)

相关问题