From 0cb9c042ac90395ad510ab04cf9442c723a60a33 Mon Sep 17 00:00:00 2001 From: Henry Nash Date: Thu, 28 Aug 2014 12:30:14 +0100 Subject: [PATCH] Add index for actor_id in assignments table. Searching the assignments table by actor_id is a common occurance and in a large OpenStack installation, this can be a significant performance degradation. This table is read much more often than it is written, so this should be a good trade off. Change-Id: Ia1a4392ca2118690a10130b10b2f69cd05672a12 Closes-bug: 1362557 --- keystone/assignment/backends/sql.py | 2 +- .../versions/054_add_actor_id_index.py | 35 +++++++++++++++++++ keystone/tests/test_sql_upgrade.py | 14 ++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 keystone/common/sql/migrate_repo/versions/054_add_actor_id_index.py diff --git a/keystone/assignment/backends/sql.py b/keystone/assignment/backends/sql.py index 1325778c2d..65241c64f9 100644 --- a/keystone/assignment/backends/sql.py +++ b/keystone/assignment/backends/sql.py @@ -638,7 +638,7 @@ class RoleAssignment(sql.ModelBase, sql.DictBase): AssignmentType.USER_DOMAIN, AssignmentType.GROUP_DOMAIN, name='type'), nullable=False) - actor_id = sql.Column(sql.String(64), nullable=False) + actor_id = sql.Column(sql.String(64), nullable=False, index=True) target_id = sql.Column(sql.String(64), nullable=False) role_id = sql.Column(sql.String(64), sql.ForeignKey('role.id'), nullable=False) diff --git a/keystone/common/sql/migrate_repo/versions/054_add_actor_id_index.py b/keystone/common/sql/migrate_repo/versions/054_add_actor_id_index.py new file mode 100644 index 0000000000..33b13b7d7b --- /dev/null +++ b/keystone/common/sql/migrate_repo/versions/054_add_actor_id_index.py @@ -0,0 +1,35 @@ +# Copyright 2014 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import sqlalchemy as sql + +ASSIGNMENT_TABLE = 'assignment' + + +def upgrade(migrate_engine): + meta = sql.MetaData() + meta.bind = migrate_engine + + assignment = sql.Table(ASSIGNMENT_TABLE, meta, autoload=True) + idx = sql.Index('ix_actor_id', assignment.c.actor_id) + idx.create(migrate_engine) + + +def downgrade(migrate_engine): + meta = sql.MetaData() + meta.bind = migrate_engine + + assignment = sql.Table(ASSIGNMENT_TABLE, meta, autoload=True) + idx = sql.Index('ix_actor_id', assignment.c.actor_id) + idx.drop(migrate_engine) diff --git a/keystone/tests/test_sql_upgrade.py b/keystone/tests/test_sql_upgrade.py index 9875d5c061..1e5c046e38 100644 --- a/keystone/tests/test_sql_upgrade.py +++ b/keystone/tests/test_sql_upgrade.py @@ -1386,6 +1386,20 @@ class SqlUpgradeTests(SqlMigrateBase): self.assertEqual(1, session.query(endpoint_table). filter_by(region=_small_region_name).count()) + def test_add_actor_id_index(self): + self.upgrade(53) + self.upgrade(54) + table = sqlalchemy.Table('assignment', self.metadata, autoload=True) + index_data = [(idx.name, idx.columns.keys()) for idx in table.indexes] + self.assertIn(('ix_actor_id', ['actor_id']), index_data) + + def test_remove_actor_id_index(self): + self.upgrade(54) + self.downgrade(53) + table = sqlalchemy.Table('assignment', self.metadata, autoload=True) + index_data = [(idx.name, idx.columns.keys()) for idx in table.indexes] + self.assertNotIn(('ix_actor_id', ['actor_id']), index_data) + def populate_user_table(self, with_pass_enab=False, with_pass_enab_domain=False): # Populate the appropriate fields in the user