或使用Postgresql查询性能和策略

时间:2010-02-23 15:55:41

标签: sql database performance postgresql

在我的应用程序中,我有一个应用程序事件表,用于生成应用程序事件的用户特定提要。因为它是使用OR查询生成的,所以我担心这个使用频繁的查询的性能,我想知道我是否接近这个错误。

在应用程序中,用户可以关注其他用户和组。执行操作时(例如,创建新帖子),将创建feed_item记录,其中actor_id设置为用户的ID,subject_id设置为组ID,其中操作已执行,actor_typesubject_type设置为模型的类名。由于用户可以关注组和用户,因此我需要生成一个检查actor_id和subject_id的查询,并且需要选择不同的记录以避免重复。由于它是OR查询,我不能使用普通索引。并且由于每次执行操作都会创建一条记录,我希望这张表能够很快地记录下来。

这是当前查询(following表将用户加入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

所以我的问题:

  • 由于这是一个使用频繁的查询,这里是否存在性能问题?

  • 有没有明显的方法来简化或优化我缺少的东西?

3 个答案:

答案 0 :(得分:1)

你所拥有的是一个叫做独家弧的东西,你就会明白为什么这是一个坏主意。解决此类问题的最佳方法是使Feed项类型动态化:

  • Feed Items:id,type(Actor或Subject的A或S),子类型(替换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条件的原因,从而使自己能够针对性能查询进行编写它

答案 1 :(得分:1)

解释分析和时间查询以查看是否存在问题。

您也可以尝试将查询表达为联合

SELECT x.* FROM
(
SELECT feed_items.* FROM feed_items
INNER JOIN followings 
ON  followings.feeder_id = feed_items.subject_id 
    AND followings.feeder_type = feed_items.subject_type
WHERE (followings.follower_id = 42)
UNION
SELECT feed_items.* FROM feed_items
INNER JOIN followings
 followings.feeder_id = feed_items.actor_id 
 AND followings.feeder_type = feed_items.actor_type)
WHERE (followings.follower_id = 42)
) AS x
ORDER BY x.created_at DESC 
LIMIT 30

但再次解释分析和基准。

答案 2 :(得分:0)

要确定是否存在性能问题。 PostgreSQL可以为你explain

我不认为查询需要简化,如果您发现性能问题,那么您可能需要修改索引。