Avoid loading network and all rels for subnet query

The Subnet model has a relationship to Network that is only
used for bumping the revision of the network. However, loading
the network loads all of its relationships as well so we end
up wasting a bunch of time loading segments, DHCP agents, etc all
for no reason. During a subnet update, we get the subnet from the
DB several times (policy engine, before update, after update,
and dhcp agent scheduler) so the slowness in get_subnet is amplified.

The recent switch to subqueries[1] has made loading all of this
unrelated data much more expensive since each relationship requires
a query, which was likely what brought this problem to the surface.

This adjusts the relationship to just load the standard attr object
of the network directly so we can still bump the revision of the network
without having to load the network itself.

This resulted in a ~20%-30% reduction of time spent in single update-subnet
operations on my dev environment (1sec to 650-850ms).

1. I6952c48236153a8e2f2f155375b70573ddc2cf0f

Closes-Bug: #1665967
Change-Id: Ie5f956ddf0704a5dde6e4f801a446f48fea5f697
This commit is contained in:
Kevin Benton
2017-02-18 21:25:30 -08:00
parent 8a1371588d
commit bc306a5512

View File

@@ -160,7 +160,11 @@ class Subnet(standard_attr.HasStandardAttributes, model_base.BASEV2,
ip_version = sa.Column(sa.Integer, nullable=False)
cidr = sa.Column(sa.String(64), nullable=False)
gateway_ip = sa.Column(sa.String(64))
revises_on_change = ('networks', )
network_standard_attr = orm.relationship(
'StandardAttribute', lazy='subquery', viewonly=True,
secondary='networks', uselist=False,
load_on_pending=True)
revises_on_change = ('network_standard_attr', )
allocation_pools = orm.relationship(IPAllocationPool,
backref='subnet',
lazy="subquery",
@@ -238,7 +242,7 @@ class Network(standard_attr.HasStandardAttributes, model_base.BASEV2,
name = sa.Column(sa.String(db_const.NAME_FIELD_SIZE))
ports = orm.relationship(Port, backref='networks')
subnets = orm.relationship(
Subnet, backref=orm.backref('networks', lazy='subquery'),
Subnet,
lazy="subquery")
status = sa.Column(sa.String(16))
admin_state_up = sa.Column(sa.Boolean)