MM-23369: Allow mysql to choose a better index (#14119)
* MM-23369: Allow mysql to choose a better index When the ORDER BY clause contains a column which is in the WHERE clause and also part of an index, mysql tries to use that specific index to avoid sorting. This is inspite of the fact that there may be other indices which are better for scanning the table and then doing a sort. Essentially, mysql becomes dumb and scans a lot of rows to avoid sorting. Whereas, it could have scanned a lot less rows and do the sorting in no time. To fix this, we use the other columns in the ORDER BY clause as well which are part of the index. This causes no change in the results because the other columns are an EQUAL condition check, but this lets mysql use the right index. Because now mysql sees that it has to order by other columns too, so it better use the other index to scan and then do the sorting. This does not affect tables of smaller size because the LIMIT of rows is always 1. And mysql will stop sorting the moment it gets the first row. So sorting is not the overhead at all. Therefore, this seems like an optimal fix. References: https://dev.mysql.com/doc/refman/5.7/en/table-scan-avoidance.html https://code.openark.org/blog/mysql/7-ways-to-convince-mysql-to-use-the-right-index https://dev.mysql.com/doc/refman/5.7/en/limit-optimization.html * Added a comment to clarify things in code * Incorporating review comments
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
32b7f477bf
Коммит
bf3c2c0ce6
@@ -770,7 +770,10 @@ func (s *SqlPostStore) getPostIdAroundTime(channelId string, time int64, before
|
||||
sq.Eq{"ChannelId": channelId},
|
||||
sq.Eq{"DeleteAt": int(0)},
|
||||
}).
|
||||
OrderBy("CreateAt " + sort).
|
||||
// Adding ChannelId and DeleteAt order columns
|
||||
// to let mysql choose the "idx_posts_channel_id_delete_at_create_at" index always.
|
||||
// See MM-23369.
|
||||
OrderBy("ChannelId", "DeleteAt", "CreateAt "+sort).
|
||||
Limit(1)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
@@ -797,7 +800,10 @@ func (s *SqlPostStore) GetPostAfterTime(channelId string, time int64) (*model.Po
|
||||
sq.Eq{"ChannelId": channelId},
|
||||
sq.Eq{"DeleteAt": int(0)},
|
||||
}).
|
||||
OrderBy("CreateAt ASC").
|
||||
// Adding ChannelId and DeleteAt order columns
|
||||
// to let mysql choose the "idx_posts_channel_id_delete_at_create_at" index always.
|
||||
// See MM-23369.
|
||||
OrderBy("ChannelId", "DeleteAt", "CreateAt ASC").
|
||||
Limit(1)
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
|
||||
Ссылка в новой задаче
Block a user