gpt4 book ai didi

sql - postgres 中的表连接顺序

转载 作者:太空狗 更新时间:2023-10-30 01:44:08 26 4
gpt4 key购买 nike

有没有办法让我在 Postgres 中强制执行特定的连接顺序?

我有一个看起来像这样的查询。我已经删除了真实查询中的一堆内容,但这种简化说明了这个问题。剩下的不应该太神秘:使用角色/任务安全系统,我试图确定给定用户是否有权执行给定任务。

select task.taskid
from userlogin
join userrole using (userloginid)
join roletask using (roleid)
join task using (taskid)
where loginname='foobar'
and taskfunction='plugh'

但我意识到该程序已经知道 userlogin 的值,因此似乎可以通过跳过对 userlogin 的查找并仅填写 userloginid 来提高查询效率,如下所示:

select task.taskid
from userrole
join roletask using (roleid)
join task using (taskid)
where userloginid=42
and taskfunction='plugh'

当我这样做时——从查询中删除一个表并硬编码从该表中检索到的值——解释计划时间增加了!在原始查询中,Postgres 读取 userlogin 然后是 userrole 然后是 roletask 然后是任务。但是在新查询中,它决定先读取 roletask,然后加入 userrole,即使这需要对 roletask 进行全文件扫描。

完整的解释计划是:

版本 1:

Hash Join  (cost=12.79..140.82 rows=1 width=8) 
Hash Cond: (roletask.taskid = task.taskid)
-> Nested Loop (cost=4.51..129.73 rows=748 width=8)
-> Nested Loop (cost=4.51..101.09 rows=12 width=8)
-> Index Scan using idx_userlogin_loginname on userlogin (cost=0.00..8.27 rows=1 width=8)
Index Cond: ((loginname)::text = 'foobar'::text)
-> Bitmap Heap Scan on userrole (cost=4.51..92.41 rows=33 width=16)
Recheck Cond: (userrole.userloginid = userlogin.userloginid)
-> Bitmap Index Scan on idx_userrole_login (cost=0.00..4.50 rows=33 width=0)
Index Cond: (userrole.userloginid = userlogin.userloginid)
-> Index Scan using idx_roletask_role on roletask (cost=0.00..1.50 rows=71 width=16)
Index Cond: (roletask.roleid = userrole.roleid)
-> Hash (cost=8.27..8.27 rows=1 width=8)
-> Index Scan using idx_task_taskfunction on task (cost=0.00..8.27 rows=1 width=8)
Index Cond: ((taskfunction)::text = 'plugh'::text)

版本 2:

Hash Join  (cost=96.58..192.82 rows=4 width=8) 
Hash Cond: (roletask.roleid = userrole.roleid)
-> Hash Join (cost=8.28..104.10 rows=9 width=16)
Hash Cond: (roletask.taskid = task.taskid)
-> Seq Scan on roletask (cost=0.00..78.35 rows=4635 width=16)
-> Hash (cost=8.27..8.27 rows=1 width=8)
-> Index Scan using idx_task_taskfunction on task (cost=0.00..8.27 rows=1 width=8)
Index Cond: ((taskfunction)::text = 'plugh'::text)
-> Hash (cost=87.92..87.92 rows=31 width=8)
-> Bitmap Heap Scan on userrole (cost=4.49..87.92 rows=31 width=8)
Recheck Cond: (userloginid = 42)
-> Bitmap Index Scan on idx_userrole_login (cost=0.00..4.49 rows=31 width=0)
Index Cond: (userloginid = 42)

(是的,我知道在这两种情况下成本都很低,而且差异看起来并不重要。但这是在我从查询中消除了一堆额外的工作以简化我必须发布的内容之后。真正的查询仍然不是离谱的,但我对原理更感兴趣。)

最佳答案

文档中的这一页描述了如何防止 PostgreSQL 优化器对连接表重新排序,从而允许您自己控制连接顺序:

http://www.postgresql.org/docs/current/interactive/explicit-joins.html

关于sql - postgres 中的表连接顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1468302/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com