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