Improve DB performance on getPostsAround() (#11662)
This change modifies the database query used by the getPostsAround() method in order to improve the performance of loading posts when scrolling through a channel.
Этот коммит содержится в:
коммит произвёл
Harrison Healey
родитель
5f61047d02
Коммит
20f03f7656
@@ -580,8 +580,7 @@ func (s *SqlPostStore) GetPostsAfter(channelId string, postId string, limit int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *SqlPostStore) getPostsAround(channelId string, postId string, limit int, offset int, before bool) (*model.PostList, *model.AppError) {
|
func (s *SqlPostStore) getPostsAround(channelId string, postId string, limit int, offset int, before bool) (*model.PostList, *model.AppError) {
|
||||||
var direction string
|
var direction, sort string
|
||||||
var sort string
|
|
||||||
if before {
|
if before {
|
||||||
direction = "<"
|
direction = "<"
|
||||||
sort = "DESC"
|
sort = "DESC"
|
||||||
@@ -590,8 +589,7 @@ func (s *SqlPostStore) getPostsAround(channelId string, postId string, limit int
|
|||||||
sort = "ASC"
|
sort = "ASC"
|
||||||
}
|
}
|
||||||
|
|
||||||
var posts []*model.Post
|
var posts, parents []*model.Post
|
||||||
var parents []*model.Post
|
|
||||||
_, err := s.GetReplica().Select(&posts,
|
_, err := s.GetReplica().Select(&posts,
|
||||||
`SELECT
|
`SELECT
|
||||||
*
|
*
|
||||||
@@ -608,38 +606,40 @@ func (s *SqlPostStore) getPostsAround(channelId string, postId string, limit int
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, model.NewAppError("SqlPostStore.GetPostContext", "store.sql_post.get_posts_around.get.app_error", nil, "channelId="+channelId+err.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("SqlPostStore.GetPostContext", "store.sql_post.get_posts_around.get.app_error", nil, "channelId="+channelId+err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(posts) > 0 {
|
||||||
|
rootIds := []string{}
|
||||||
|
for _, post := range posts {
|
||||||
|
rootIds = append(rootIds, post.Id)
|
||||||
|
if post.RootId != "" {
|
||||||
|
rootIds = append(rootIds, post.RootId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keys, params := MapStringsToQueryParams(rootIds, "PostId")
|
||||||
|
|
||||||
|
params["ChannelId"] = channelId
|
||||||
|
params["PostId"] = postId
|
||||||
|
params["Limit"] = limit
|
||||||
|
params["Offset"] = offset
|
||||||
|
|
||||||
_, err = s.GetReplica().Select(&parents,
|
_, err = s.GetReplica().Select(&parents,
|
||||||
`SELECT
|
`SELECT
|
||||||
q2.*
|
*
|
||||||
FROM
|
|
||||||
Posts q2
|
|
||||||
INNER JOIN
|
|
||||||
(SELECT DISTINCT
|
|
||||||
q3.Id, q3.RootId
|
|
||||||
FROM
|
|
||||||
(SELECT
|
|
||||||
Id, RootId
|
|
||||||
FROM
|
FROM
|
||||||
Posts
|
Posts
|
||||||
WHERE
|
WHERE
|
||||||
CreateAt `+direction+` (SELECT CreateAt FROM Posts WHERE Id = :PostId)
|
(Id IN `+keys+` OR RootId IN `+keys+`)
|
||||||
AND ChannelId = :ChannelId
|
AND ChannelId = :ChannelId
|
||||||
AND DeleteAt = 0
|
AND DeleteAt = 0
|
||||||
ORDER BY CreateAt `+sort+`
|
|
||||||
LIMIT :Limit OFFSET :Offset) q3 -- q3 contains the Id and RootId of every post in posts
|
|
||||||
) q1 -- q1 is q3 with the duplicates removed
|
|
||||||
ON q1.RootId = q2.Id -- This is the root post of a thread that appears in posts
|
|
||||||
OR q1.Id = q2.RootId -- This is a comment on a post in posts
|
|
||||||
OR (q2.RootId != '' AND q1.RootId = q2.RootId) -- This is a comment on a thread that appears in posts
|
|
||||||
WHERE
|
|
||||||
ChannelId = :ChannelId
|
|
||||||
AND DeleteAt = 0
|
|
||||||
ORDER BY CreateAt DESC`,
|
ORDER BY CreateAt DESC`,
|
||||||
map[string]interface{}{"ChannelId": channelId, "PostId": postId, "Limit": limit, "Offset": offset})
|
params)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, model.NewAppError("SqlPostStore.GetPostContext", "store.sql_post.get_posts_around.get_parent.app_error", nil, "channelId="+channelId+err.Error(), http.StatusInternalServerError)
|
return nil, model.NewAppError("SqlPostStore.GetPostContext", "store.sql_post.get_posts_around.get_parent.app_error", nil, "channelId="+channelId+err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
list := model.NewPostList()
|
list := model.NewPostList()
|
||||||
|
|
||||||
// We need to flip the order if we selected backwards
|
// We need to flip the order if we selected backwards
|
||||||
@@ -659,6 +659,7 @@ func (s *SqlPostStore) getPostsAround(channelId string, postId string, limit int
|
|||||||
for _, p := range parents {
|
for _, p := range parents {
|
||||||
list.AddPost(p)
|
list.AddPost(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user