Avoid unnecessary joins in InstanceGroup.get_hosts
The InstanceList.get_by_filters query is joining on
info_cache, security_groups, metadata and system_metadata
because of how instance_get_all_by_filters_sort in the DB API
works if columns_to_join (expected_attrs) is None. The get_hosts
method only cares about the instance.host value of its members
so those joins are unnecessarily expensive.
This change simply passes expected_attrs=[] to get_by_filters
to avoid the joins. A follow up change can further optimize this
code by adding a new query method to just get the host values
for a list of instance uuids, so a TODO is left in place for that.
Note that a new query method would need to be remotable and thus
not something we can backport.
Change-Id: I53d4b38d12404a1641f667c537404effa837a83d
Partial-Bug: #1830234
(cherry picked from commit 15ccf2ddfb
)
This commit is contained in:
parent
105e6238dd
commit
74e66fe8d4
|
@ -497,8 +497,15 @@ class InstanceGroup(base.NovaPersistentObject, base.NovaObject,
|
|||
if exclude:
|
||||
filter_uuids = set(filter_uuids) - set(exclude)
|
||||
filters = {'uuid': filter_uuids, 'deleted': False}
|
||||
# Pass expected_attrs=[] to avoid unnecessary joins.
|
||||
# TODO(mriedem): This is pretty inefficient since all we care about
|
||||
# are the hosts. We could optimize this with a single-purpose SQL query
|
||||
# like:
|
||||
# SELECT host FROM instances WHERE deleted=0 AND host IS NOT NULL
|
||||
# AND uuid IN ($filter_uuids) GROUP BY host;
|
||||
instances = objects.InstanceList.get_by_filters(self._context,
|
||||
filters=filters)
|
||||
filters=filters,
|
||||
expected_attrs=[])
|
||||
return list(set([instance.host for instance in instances
|
||||
if instance.host]))
|
||||
|
||||
|
|
|
@ -280,7 +280,8 @@ class _TestInstanceGroupObject(object):
|
|||
'deleted': False
|
||||
}
|
||||
mock_il_get.assert_called_once_with(self.context,
|
||||
filters=expected_filters)
|
||||
filters=expected_filters,
|
||||
expected_attrs=[])
|
||||
self.assertEqual(2, len(hosts))
|
||||
self.assertIn('host1', hosts)
|
||||
self.assertIn('host2', hosts)
|
||||
|
@ -293,7 +294,8 @@ class _TestInstanceGroupObject(object):
|
|||
'deleted': False
|
||||
}
|
||||
mock_il_get.assert_called_once_with(self.context,
|
||||
filters=expected_filters)
|
||||
filters=expected_filters,
|
||||
expected_attrs=[])
|
||||
|
||||
def test_obj_make_compatible(self):
|
||||
obj = objects.InstanceGroup(self.context, **_INST_GROUP_OBJ_VALS)
|
||||
|
|
Loading…
Reference in New Issue