在我的应用程序中,我有一个应用程序事件表,用于生成特定于用户的应用程序事件提要。因为它是使用 OR 查询生成的,所以我很担心这个频繁使用的查询的性能,并且想知道我是否正在处理这个问题。
在应用程序中,用户可以关注其他用户和群组。执行操作时(例如,创建新帖子),将创建一个 feed_item
记录,其中 actor_id
设置为用户 ID 和 subject_id
设置为执行操作的组 ID,actor_type
和 subject_type
设置为模型的类名。由于用户可以关注组和用户,我需要生成一个查询来检查 actor_id 和 subject_id,并且它需要选择不同的记录以避免重复。由于它是一个 OR 查询,我不能使用普通索引。由于每次执行操作时都会创建一条记录,因此我希望该表很快就会有很多记录。
这是当前查询(下面的
表将用户加入到feeders
,也就是用户和组)
SELECT DISTINCT feed_items.* FROM "feed_items"
INNER JOIN "followings"
ON (
(followings.feeder_id = feed_items.subject_id
AND followings.feeder_type = feed_items.subject_type)
OR
(followings.feeder_id = feed_items.actor_id
AND followings.feeder_type = feed_items.actor_type)
)
WHERE (followings.follower_id = 42) ORDER BY feed_items.created_at DESC LIMIT 30 OFFSET 0
所以我的问题:
由于这是一个频繁使用的查询,这里是否存在性能问题?
是否有任何明显的方法可以简化或优化我所缺少的?
最佳答案
您所拥有的称为独占弧,并且您明白为什么这是个坏主意。解决此类问题的最佳方法是使提要项类型动态化:
- Feed 项目:id、类型(A 或 S 代表 Actor 或主题)、子类型(替换 actor_type 和 subject_type)
然后你的查询就变成了
SELECT DISTINCT fi.*
FROM feed_items fi
JOIN followings f ON f.feeder_id = fi.id AND f.feeder_type = fi.type AND f.feeder_subtype = fi.subtype
或类似的。
这可能不完全或不完全代表您需要做的事情,但原则是合理的:您需要通过更改数据模型来消除 OR 条件的原因,使其适合于编写针对其执行的高性能查询
关于sql - 使用 Postgresql 的 OR 查询性能和策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2319552/