我想讨论这个简单的postgres查询,并弄清楚我是否已经掌握了postgres和DB背后的一些理论。它来了:
-- Query 1
SELECT posts.*, users.*
FROM posts INNER JOIN users
ON posts.user_id = users.id
WHERE
posts.user_id = :id
ORDER BY posts.creation_time
它显然涉及两个连接在一起的表(users
和posts
)。 (posts.creation_time
,posts.user_id
)上有一个索引可以加快搜索速度。
我的理解是,我还需要一个将posts.user_id
与users.id
联系起来的外键,不仅可以强制执行一种形式的参照完整性,而且可能更重要的是,加快ON posts.user_id = users.id
位查询。
我这样说是对吗?
现在考虑这个版本的查询:
-- Query 2
SELECT posts.*, users.*
FROM posts INNER JOIN users
ON posts.user_id = users.id
WHERE
users.id = :id
ORDER BY posts.creation_time
假设存在上述外键(posts.creation_time
,posts.user_id
),考虑到等式中的变量是否存在于连接的另一端,此查询是否会缩放?
我的猜测是它不会缩放
由于
答案 0 :(得分:0)
查看这篇文章:
Postgres and Indexes on Foreign Keys and Primary Keys
外键是维护数据参照完整性所必需的。索引有助于提高查询速度。创建外键不会自动创建索引。
答案 1 :(得分:0)
如果某个查询需要FK索引,则取决于查询执行计划。如果从子项开始,则使用PK索引查找相应的父行。如果从父端开始,则需要一个有效地查找相应的子行。但请记住,可能会发生一些隐式查询,例如:从父表中删除行必须确保没有相应的子行。 因此,在大多数情况下,最好在FK上添加索引。
我不确定postgresql,但是在oracle中没有在FK上创建索引甚至可能在删除父行时导致表锁。
还要记住,对于通过“和”(显式或隐式用于连接)组合的条件,您通常只能在给定查询中为每个表使用一个索引。在您的示例中,我将在表posts
上添加一个组合索引,列user_id, creation_time
(按此顺序),以适合两者
WHERE posts.user_id = :id
和
ORDER BY posts.creation_time
同时