Improve the performance of artifact related APIs

Improve the performance of artifact related APIs by adding indexes and refactoring sql logic

Closes #13890 #14813 #14814

Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
Wenkai Yin 2021-05-20 11:25:43 +08:00
parent 08ed886936
commit dc059a9a8f
2 changed files with 23 additions and 18 deletions

View File

@ -1,2 +1,7 @@
ALTER TABLE replication_policy ADD COLUMN IF NOT EXISTS dest_namespace_replace_count int;
UPDATE replication_policy SET dest_namespace_replace_count=-1 WHERE dest_namespace IS NULL;
CREATE INDEX IF NOT EXISTS idx_artifact_push_time ON artifact (push_time);
CREATE INDEX IF NOT EXISTS idx_tag_push_time ON tag (push_time);
CREATE INDEX IF NOT EXISTS idx_tag_artifact_id ON tag (artifact_id);
CREATE INDEX IF NOT EXISTS idx_artifact_reference_child_id ON artifact_reference (child_id);

View File

@ -53,22 +53,22 @@ type DAO interface {
}
const (
// both tagged and untagged artifacts
both = `IN (
SELECT DISTINCT art.id FROM artifact art
LEFT JOIN tag ON art.id=tag.artifact_id
LEFT JOIN artifact_reference ref ON art.id=ref.child_id
WHERE tag.id IS NOT NULL OR ref.id IS NULL)`
// only untagged artifacts
untagged = `IN (
SELECT DISTINCT art.id FROM artifact art
LEFT JOIN tag ON art.id=tag.artifact_id
WHERE tag.id IS NULL)`
// only tagged artifacts
tagged = `IN (
SELECT DISTINCT art.id FROM artifact art
JOIN tag ON art.id=tag.artifact_id
WHERE tag.id IS NOT NULL)`
// the QuerySetter of beego doesn't support "EXISTS" directly, use qs.FilterRaw("id", "=id AND xxx") to workaround the limitation
// base filter: both tagged and untagged artifacts
both = `=id AND (
EXISTS (SELECT 1 FROM tag WHERE tag.artifact_id = T0.id)
OR
NOT EXISTS (SELECT 1 FROM artifact_reference ref WHERE ref.child_id = T0.id)
)`
// tag filter: only untagged artifacts
// the "untagged" filter is based on "base" filter, so we consider the tag only
untagged = `=id AND NOT EXISTS(
SELECT 1 FROM tag WHERE tag.artifact_id = T0.id
)`
// tag filter: only tagged artifacts
tagged = `=id AND EXISTS (
SELECT 1 FROM tag WHERE tag.artifact_id = T0.id
)`
)
// New returns an instance of the default DAO
@ -273,7 +273,7 @@ func querySetter(ctx context.Context, query *q.Query) (beegoorm.QuerySeter, erro
// handle q=base=*
// when "q=base=*" is specified in the query, the base collection is the all artifacts of database,
// otherwise the base connection is only the tagged artifacts and untagged artifacts that aren't
// otherwise the base collection is only the tagged artifacts and untagged artifacts that aren't
// referenced by others
func setBaseQuery(qs beegoorm.QuerySeter, query *q.Query) (beegoorm.QuerySeter, error) {
if query == nil || len(query.Keywords) == 0 {