Speed up loading a change with eager loading

To display a change screen, we need to access all of the revisions,
files, and comments for the change.  Tell SQLAlchemy in that case
to go ahead and load everything in one query.  In local testing,
this made https://review.openstack.org/223333 load in about 1
second rather than 9 seconds.

Change-Id: I5eb53e2a1ee853f4489e92c4ca719cfb96b4a563
This commit is contained in:
James E. Blair 2016-07-18 13:53:03 -07:00
parent 24790ecc23
commit 0f0b1b149a
2 changed files with 7 additions and 4 deletions

View File

@ -24,7 +24,7 @@ import six
import sqlalchemy import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, Boolean, DateTime, Text, UniqueConstraint from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, Boolean, DateTime, Text, UniqueConstraint
from sqlalchemy.schema import ForeignKey from sqlalchemy.schema import ForeignKey
from sqlalchemy.orm import mapper, sessionmaker, relationship, scoped_session from sqlalchemy.orm import mapper, sessionmaker, relationship, scoped_session, joinedload
from sqlalchemy.orm.session import Session from sqlalchemy.orm.session import Session
from sqlalchemy.sql import exists from sqlalchemy.sql import exists
from sqlalchemy.sql.expression import and_ from sqlalchemy.sql.expression import and_
@ -815,9 +815,12 @@ class DatabaseSession(object):
except sqlalchemy.orm.exc.NoResultFound: except sqlalchemy.orm.exc.NoResultFound:
return self.createSyncQuery(name) return self.createSyncQuery(name)
def getChange(self, key): def getChange(self, key, lazy=True):
query = self.session().query(Change).filter_by(key=key)
if not lazy:
query = query.options(joinedload(Change.revisions).joinedload(Revision.files).joinedload(File.comments))
try: try:
return self.session().query(Change).filter_by(key=key).one() return query.one()
except sqlalchemy.orm.exc.NoResultFound: except sqlalchemy.orm.exc.NoResultFound:
return None return None

View File

@ -618,7 +618,7 @@ class ChangeView(urwid.WidgetWrap):
def refresh(self): def refresh(self):
with self.app.db.getSession() as session: with self.app.db.getSession() as session:
change = session.getChange(self.change_key) change = session.getChange(self.change_key, lazy=False)
# When we first open the change, update its last_seen # When we first open the change, update its last_seen
# time. # time.
if not self.marked_seen: if not self.marked_seen: