Skip to content

Commit

Permalink
satellite/metabase: optimize ListObjects
Browse files Browse the repository at this point in the history
By using MAX we can avoid needing to sort all the objects in memory.

Updates #6734

Change-Id: I5cb17dcf058197500ad5c7b73437af195b681d8e
  • Loading branch information
egonelbre authored and Storj Robot committed Feb 5, 2024
1 parent f60620b commit 4dee76f
Showing 1 changed file with 6 additions and 13 deletions.
19 changes: 6 additions & 13 deletions satellite/metabase/list_objects.go
Expand Up @@ -101,7 +101,7 @@ func (opts *ListObjects) getSQLQuery() string {
} else {
if opts.AllVersions {
indexFields = `
DISTINCT ON (entry_key, entry_version)
DISTINCT ON (project_id, bucket_name, entry_key, entry_version)
(CASE
WHEN position('/' IN substring(object_key from $7)) <> 0
THEN substring(substring(object_key from $7) from 0 for (position('/' IN substring(object_key from $7)) +1))
Expand All @@ -117,7 +117,7 @@ func (opts *ListObjects) getSQLQuery() string {
position('/' IN substring(object_key from $7)) <> 0 AS is_prefix`
} else {
indexFields = `
DISTINCT ON (entry_key)
DISTINCT ON (project_id, bucket_name, entry_key)
(CASE
WHEN position('/' IN substring(object_key from $7)) <> 0
THEN substring(substring(object_key from $7) from 0 for (position('/' IN substring(object_key from $7)) +1))
Expand All @@ -143,10 +143,6 @@ func (opts *ListObjects) getSQLQuery() string {
`

case !opts.Pending && !opts.AllVersions:
// The following subquery for the highest-version can also be implemented via
// SELECT MAX(sub.version) FROM objects ...
// however, that seems slower on benchmarks.

// query committed objects where the latest is not a delete marker
return `SELECT ` + indexFields + opts.selectedFields() + `
FROM objects main
Expand All @@ -156,14 +152,11 @@ func (opts *ListObjects) getSQLQuery() string {
AND status IN ` + statusesCommitted + `
AND (expires_at IS NULL OR expires_at > now())
AND version = (
SELECT sub.version
SELECT MAX(sub.version)
FROM objects sub
WHERE
(sub.project_id, sub.bucket_name, sub.object_key) = (main.project_id, main.bucket_name, main.object_key)
WHERE (sub.project_id, sub.bucket_name, sub.object_key) = (main.project_id, main.bucket_name, main.object_key)
AND status <> ` + statusPending + `
AND (expires_at IS NULL OR expires_at > now())
ORDER BY version DESC
LIMIT 1
)
ORDER BY ` + opts.orderBy() + `
LIMIT $6
Expand All @@ -189,9 +182,9 @@ func (opts *ListObjects) stopCondition() string {

func (opts *ListObjects) orderBy() string {
if opts.Pending {
return "entry_key ASC, entry_version ASC"
return "project_id ASC, bucket_name ASC, entry_key ASC, entry_version ASC"
} else {
return "entry_key ASC, entry_version DESC"
return "project_id ASC, bucket_name ASC, entry_key ASC, entry_version DESC"
}
}

Expand Down

0 comments on commit 4dee76f

Please sign in to comment.