Remove double join in provider_ids_from_rp_ids
provider_ids_from_rp_ids is only used in _build_provider_summaries. It is passed a collection of usages dict created _get_usages_by_provider_tree this has usage information for _all_ the providers in the contributing trees, even those providers that do not provide any resources (otherwise we wouldn't be able to build a complete summary). This means that the list of rp ids passed to provider_ids_from_rp_ids includes all the relevant rps and the returned data structure can itself be used to find root_provider_uuid and parent_provider_uuid, instead of doing the join. This speeds up the database query. Combined with the expanding bindparam in the previous patch, this cleans up provider_ids_from_rp_ids nicely. Change-Id: If937053a8af3f0eecdd90aa807be0abc316d8c4f
This commit is contained in:
@@ -508,11 +508,13 @@ def _build_provider_summaries(context, rw_ctx, usages, prov_traits):
|
||||
summary = rw_ctx.summaries_by_id.get(rp_id)
|
||||
if not summary:
|
||||
pids = provider_ids[rp_id]
|
||||
parent_id = pids.parent_id
|
||||
parent_uuid = provider_ids[parent_id].uuid if parent_id else None
|
||||
summary = ProviderSummary(
|
||||
resource_provider=rp_obj.ResourceProvider(
|
||||
context, id=pids.id, uuid=pids.uuid,
|
||||
root_provider_uuid=pids.root_uuid,
|
||||
parent_provider_uuid=pids.parent_uuid),
|
||||
root_provider_uuid=provider_ids[pids.root_id].uuid,
|
||||
parent_provider_uuid=parent_uuid),
|
||||
resources=[],
|
||||
)
|
||||
summary.traits = prov_traits[rp_id]
|
||||
|
||||
@@ -310,32 +310,17 @@ def provider_ids_from_rp_ids(context, rp_ids):
|
||||
:param rp_ids: iterable of internal provider IDs to look up
|
||||
"""
|
||||
# SELECT
|
||||
# rp.id, rp.uuid,
|
||||
# parent.id AS parent_id, parent.uuid AS parent_uuid,
|
||||
# root.id AS root_id, root.uuid AS root_uuid
|
||||
# rp.id, rp.uuid, rp.parent_provider_id, rp.root_provider.id
|
||||
# FROM resource_providers AS rp
|
||||
# INNER JOIN resource_providers AS root
|
||||
# ON rp.root_provider_id = root.id
|
||||
# LEFT JOIN resource_providers AS parent
|
||||
# ON rp.parent_provider_id = parent.id
|
||||
# WHERE rp.id IN ($rp_ids)
|
||||
me = sa.alias(_RP_TBL, name="me")
|
||||
parent = sa.alias(_RP_TBL, name="parent")
|
||||
root = sa.alias(_RP_TBL, name="root")
|
||||
cols = [
|
||||
me.c.id,
|
||||
me.c.uuid,
|
||||
parent.c.id.label('parent_id'),
|
||||
parent.c.uuid.label('parent_uuid'),
|
||||
root.c.id.label('root_id'),
|
||||
root.c.uuid.label('root_uuid'),
|
||||
me.c.parent_provider_id.label('parent_id'),
|
||||
me.c.root_provider_id.label('root_id'),
|
||||
]
|
||||
me_to_root = sa.join(me, root, me.c.root_provider_id == root.c.id)
|
||||
me_to_parent = sa.outerjoin(
|
||||
me_to_root, parent,
|
||||
me.c.parent_provider_id == parent.c.id)
|
||||
sel = sa.select(cols).select_from(me_to_parent)
|
||||
sel = sel.where(me.c.id.in_(sa.bindparam('rps', expanding=True)))
|
||||
sel = sa.select(cols).where(me.c.id.in_(rp_ids))
|
||||
|
||||
ret = {}
|
||||
for r in context.session.execute(sel, {'rps': list(rp_ids)}):
|
||||
|
||||
Reference in New Issue
Block a user