Query performance enhancements in get_requiredby()

For packages with particularly long lists of provides (e.g. perl), the
query was getting a bit out of control with the list of names passed in.
However, changing it to simply do a subquery resulted in some really
poor planning by PostgreSQL. Doing this as a custom 'WHERE' clause
utilizing the 'UNION ALL' SQL operator works very well.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2013-01-20 14:59:30 -06:00
parent dd8e94f697
commit 1b1b516bd8

View File

@ -190,12 +190,13 @@ def get_requiredby(self):
category as this package if that check makes sense.
"""
from packages.models import Depend
provides = self.provides.all()
provide_names = {provide.name for provide in provides}
provide_names.add(self.pkgname)
name_clause = '''packages_depend.name IN (
SELECT %s UNION ALL
SELECT z.name FROM packages_provision z WHERE z.pkg_id = %s
)'''
requiredby = Depend.objects.select_related('pkg',
'pkg__arch', 'pkg__repo').filter(
name__in=provide_names).order_by(
'pkg__arch', 'pkg__repo').extra(
where=[name_clause], params=[self.pkgname, self.id]).order_by(
'pkg__pkgname', 'pkg__arch__name', 'pkg__repo__name')
if not self.arch.agnostic:
# make sure we match architectures if possible