From fe8f19ec2b4b6239c44f07e7629d3e9fdfb8d44b Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Mar 26 2020 14:00:58 +0000 Subject: PR#2074: Limit final query by prechecking buildroot ids Merges #2074 https://pagure.io/koji/pull-request/2074 Fixes: #1562 https://pagure.io/koji/issue/1562 Increase SQL effectivity in query_buildroots --- diff --git a/hub/kojihub.py b/hub/kojihub.py index fa13a4a..06fadb8 100644 --- a/hub/kojihub.py +++ b/hub/kojihub.py @@ -5323,15 +5323,46 @@ def query_buildroots(hostID=None, tagID=None, state=None, rpmID=None, archiveID= clauses.append('standard_buildroot.state IN %(state)s') else: clauses.append('standard_buildroot.state = %(state)i') + + # following filters can dramatically limit overall query size + # run separate queries for picking smallest candidate set + candidate_buildroot_ids = set() if rpmID is not None: joins.insert(0, 'buildroot_listing ON buildroot.id = buildroot_listing.buildroot_id') fields.append(('buildroot_listing.is_update', 'is_update')) clauses.append('buildroot_listing.rpm_id = %(rpmID)i') + query = QueryProcessor(columns=['buildroot_id'], tables=['buildroot_listing'], + clauses=['rpm_id = %(rpmID)i'], opts={'asList': True}, + values=locals()) + result = set(query.execute()) + candidate_buildroot_ids = result + if archiveID is not None: - joins.append('buildroot_archives ON buildroot.id = buildroot_archives.buildroot_id') + joins.insert(0, 'buildroot_archives ON buildroot.id = buildroot_archives.buildroot_id') clauses.append('buildroot_archives.archive_id = %(archiveID)i') + query = QueryProcessor(columns=['buildroot_id'], tables=['buildroot_archives'], + clauses=['archive_id = %(archiveID)i'], opts={'asList': True}, + values=locals()) + result = set(query.execute()) + if candidate_buildroot_ids: + candidate_buildroot_ids &= result + else: + candidate_buildroot_ids = result + if taskID is not None: clauses.append('standard_buildroot.task_id = %(taskID)i') + query = QueryProcessor(columns=['buildroot_id'], tables=['standard_buildroot'], + clauses=['task_id = %(taskID)i'], opts={'asList': True}, + values=locals()) + result = set(query.execute()) + if candidate_buildroot_ids: + candidate_buildroot_ids &= result + else: + candidate_buildroot_ids = result + + if candidate_buildroot_ids: + candidate_buildroot_ids = list(candidate_buildroot_ids) + clauses.append('buildroot.id IN %(candidate_buildroot_ids)s') query = QueryProcessor(columns=[f[0] for f in fields], aliases=[f[1] for f in fields], tables=tables, joins=joins, clauses=clauses, values=locals(),