From 320ef645c84fbebdfd216574f0ff1b5623b26acc Mon Sep 17 00:00:00 2001 From: John Tran Date: Wed, 24 Oct 2012 00:06:53 +0000 Subject: [PATCH] Fix sqlalchemy performance problem Fixes bug #1070074 too much lazy loading on the default model. Removed those and only added lazy loading to queries that specifically need eager loading Change-Id: Ifa7446bddef855ae8e8b76040ba3336a53606215 --- ceilometer/storage/impl_sqlalchemy.py | 11 ++++++----- ceilometer/storage/sqlalchemy/models.py | 22 +++++++++------------- ceilometer/storage/sqlalchemy/session.py | 5 ----- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/ceilometer/storage/impl_sqlalchemy.py b/ceilometer/storage/impl_sqlalchemy.py index 14dc0084b..ddf5e00c1 100644 --- a/ceilometer/storage/impl_sqlalchemy.py +++ b/ceilometer/storage/impl_sqlalchemy.py @@ -24,8 +24,7 @@ from ceilometer.openstack.common import cfg from ceilometer.storage import base from ceilometer.storage.sqlalchemy.models import Meter, Project, Resource from ceilometer.storage.sqlalchemy.models import Source, User -from ceilometer.storage.sqlalchemy.session import get_session -import ceilometer.storage.sqlalchemy.session as session +import ceilometer.storage.sqlalchemy.session as sqlalchemy_session LOG = log.getLogger(__name__) @@ -109,7 +108,7 @@ class Connection(base.Connection): def _get_connection(self, conf): """Return a connection to the database. """ - return session.get_session() + return sqlalchemy_session.get_session() def record_metering_data(self, data): """Write the data to the backend storage system. @@ -222,6 +221,8 @@ class Connection(base.Connection): query = query.filter(Resource.timestamp < end_timestamp) if project is not None: query = query.filter(Resource.project_id == project) + query = query.options( + sqlalchemy_session.sqlalchemy.orm.joinedload('meters')) for resource in query.all(): r = row2dict(resource) @@ -262,7 +263,7 @@ class Connection(base.Connection): ( datetime.datetime(), datetime.datetime() ) """ - func = session.func() + func = sqlalchemy_session.sqlalchemy.func query = self.session.query(func.min(Meter.timestamp), func.max(Meter.timestamp)) query = make_query_from_filter(query, event_filter) @@ -279,7 +280,7 @@ def model_query(*args, **kwargs): :param session: if present, the session to use """ - session = kwargs.get('session') or get_session() + session = kwargs.get('session') or sqlalchemy_session.get_session() query = session.query(*args) return query diff --git a/ceilometer/storage/sqlalchemy/models.py b/ceilometer/storage/sqlalchemy/models.py index 00eb5b28c..953dcaa9d 100644 --- a/ceilometer/storage/sqlalchemy/models.py +++ b/ceilometer/storage/sqlalchemy/models.py @@ -96,8 +96,7 @@ class Meter(Base): __tablename__ = 'meter' id = Column(Integer, primary_key=True) counter_name = Column(String(255)) - sources = relationship("Source", secondary=lambda: sourceassoc, - lazy='joined') + sources = relationship("Source", secondary=lambda: sourceassoc) user_id = Column(String(255), ForeignKey('user.id')) project_id = Column(String(255), ForeignKey('project.id')) resource_id = Column(String(255), ForeignKey('resource.id')) @@ -112,29 +111,26 @@ class Meter(Base): class User(Base): __tablename__ = 'user' id = Column(String(255), primary_key=True) - sources = relationship("Source", secondary=lambda: sourceassoc, - lazy='joined') - resources = relationship("Resource", backref='user', lazy='joined') - meters = relationship("Meter", backref='user', lazy='joined') + sources = relationship("Source", secondary=lambda: sourceassoc) + resources = relationship("Resource", backref='user') + meters = relationship("Meter", backref='user') class Project(Base): __tablename__ = 'project' id = Column(String(255), primary_key=True) - sources = relationship("Source", secondary=lambda: sourceassoc, - lazy='joined') - resources = relationship("Resource", backref='project', lazy='joined') - meters = relationship("Meter", backref='project', lazy='joined') + sources = relationship("Source", secondary=lambda: sourceassoc) + resources = relationship("Resource", backref='project') + meters = relationship("Meter", backref='project') class Resource(Base): __tablename__ = 'resource' id = Column(String(255), primary_key=True) - sources = relationship("Source", secondary=lambda: sourceassoc, - lazy='joined') + sources = relationship("Source", secondary=lambda: sourceassoc) timestamp = Column(DateTime) resource_metadata = Column(JSONEncodedDict) received_timestamp = Column(DateTime, default=timeutils.utcnow) user_id = Column(String(255), ForeignKey('user.id')) project_id = Column(String(255), ForeignKey('project.id')) - meters = relationship("Meter", backref='resource', lazy='joined') + meters = relationship("Meter", backref='resource') diff --git a/ceilometer/storage/sqlalchemy/session.py b/ceilometer/storage/sqlalchemy/session.py index db2bc5a2d..858037c14 100644 --- a/ceilometer/storage/sqlalchemy/session.py +++ b/ceilometer/storage/sqlalchemy/session.py @@ -189,8 +189,3 @@ def get_maker(engine, autocommit=True, expire_on_commit=False, autoflush=True): autocommit=autocommit, autoflush=autoflush, expire_on_commit=expire_on_commit) - - -def func(): - # ugly hack sqlalchemy name conflict from impl_sqlalchemy - return sqlalchemy.func