MM-30892: Avoid unnecessary table scan in AnalyticsPostCount. (#16643)

* MM-30892: Avoid unnecessary table scan in AnalyticsPostCount.

[AnalyticsPostCount](d9e8402dc2/store/sqlstore/post_store.go (L1513-L1541)) unconditionally joins on the `Channels` table even when not filtering to a team.

This is a proposal to stop doing this, reducing this to a simple index query when no team is specified. Note that this is technically a subtle semantic difference, since orphaned posts (from deleted or invalid channel ids) are currently excluded. But I submit the benefits outweigh the technical differences here.

Fixes: https://mattermost.atlassian.net/browse/MM-30892

* Update store/sqlstore/post_store.go

Co-authored-by: Claudio Costa <cstcld91@gmail.com>

* Update store/sqlstore/post_store.go

Co-authored-by: Claudio Costa <cstcld91@gmail.com>

Co-authored-by: Claudio Costa <cstcld91@gmail.com>
Этот коммит содержится в:
Jesse Hallam
2021-01-11 14:01:47 -04:00
коммит произвёл GitHub
родитель 2a63b5552a
Коммит 9667c96f97
2 изменённых файлов: 39 добавлений и 12 удалений

Просмотреть файл

@@ -1511,28 +1511,30 @@ func (s *SqlPostStore) AnalyticsPostCountsByDay(options *model.AnalyticsPostCoun
}
func (s *SqlPostStore) AnalyticsPostCount(teamId string, mustHaveFile bool, mustHaveHashtag bool) (int64, error) {
query :=
`SELECT
COUNT(Posts.Id) AS Value
FROM
Posts,
Channels
WHERE
Posts.ChannelId = Channels.Id`
query := s.getQueryBuilder().
Select("COUNT(p.Id) AS Value").
From("Posts p")
if len(teamId) > 0 {
query += " AND Channels.TeamId = :TeamId"
query = query.
Join("Channels c ON (c.Id = p.ChannelId)").
Where(sq.Eq{"c.TeamId": teamId})
}
if mustHaveFile {
query += " AND (Posts.FileIds != '[]' OR Posts.Filenames != '[]')"
query = query.Where(sq.Or{sq.NotEq{"p.FileIds": "[]"}, sq.NotEq{"p.Filenames": "[]"}})
}
if mustHaveHashtag {
query += " AND Posts.Hashtags != ''"
query = query.Where(sq.NotEq{"p.Hashtags": ""})
}
v, err := s.GetReplica().SelectInt(query, map[string]interface{}{"TeamId": teamId})
queryString, args, err := query.ToSql()
if err != nil {
return 0, errors.Wrap(err, "post_tosql")
}
v, err := s.GetReplica().SelectInt(queryString, args...)
if err != nil {
return 0, errors.Wrap(err, "failed to count Posts")
}