Add explicit foreign key indexes

The artifact, provides, and build_event tables all have foreign key
references to the build table.  In MySQL this causes an automatic
index to be created, but that does not appear to be the case in
Postgres.  Without these indexes, many of the queries we do can be
quite costly.

To address this, explicitly create these indexes.  Under MySQL, this
will simply rename the existing indexes, so this should be safe
and effective for both systems.

Change-Id: I16223fba75c1295480431d03ac59f72a5281b498
This commit is contained in:
James E. Blair
2023-07-10 12:46:46 -07:00
parent 6e935f3ad7
commit a2b7c8ae7c
3 changed files with 58 additions and 9 deletions
+1 -9
View File
@@ -93,16 +93,8 @@ class TestSQLConnectionMysql(ZuulTestCase):
indexes_buildset = insp.get_indexes(buildset_table)
indexes_build = insp.get_indexes(build_table)
# Remove implicitly generated indexes by the foreign key.
# MySQL creates an implicit index with the name if the column (which
# is not a problem as in MySQL the index names are scoped within the
# table). This is an implementation detail of the db engine so don't
# check this.
indexes_build = [x for x in indexes_build
if x['name'] != 'buildset_id']
self.assertEqual(4, len(indexes_buildset))
self.assertEqual(2, len(indexes_build))
self.assertEqual(3, len(indexes_build))
# check if all indexes are prefixed
if table_prefix:
@@ -0,0 +1,49 @@
# Copyright 2023 Acme Gating, LLC
#
# 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.
"""build_idx
Revision ID: 151893067f91
Revises: 0ed5def089e2
Create Date: 2023-07-05 11:50:03.931815
"""
# revision identifiers, used by Alembic.
revision = '151893067f91'
down_revision = '0ed5def089e2'
branch_labels = None
depends_on = None
from alembic import op
def upgrade(table_prefix=''):
# Create indexes like:
# artifact_build_idx on zuul_artifact.build_id
# This happens automatically on foreign keys in mysql but must be
# done explicitly in postgres.
for suffix in ['artifact',
'provides',
'build_event']:
op.create_index(
f'{table_prefix}{suffix}_build_id_idx',
f'{table_prefix}zuul_{suffix}', ['build_id'])
op.create_index(
f'{table_prefix}build_buildset_id_idx',
f'{table_prefix}zuul_build', ['buildset_id'])
def downgrade():
raise Exception("Downgrades not supported")
+8
View File
@@ -472,6 +472,8 @@ class SQLConnection(BaseConnection):
job_name, buildset_id)
sa.Index(self.table_prefix + 'uuid_buildset_id_idx',
uuid, buildset_id)
sa.Index(self.table_prefix + 'build_buildset_id_idx',
buildset_id)
@property
def duration(self):
@@ -529,6 +531,8 @@ class SQLConnection(BaseConnection):
backref=orm.backref(
"artifacts",
cascade="all, delete-orphan"))
sa.Index(self.table_prefix + 'artifact_build_id_idx',
build_id)
class ProvidesModel(Base):
__tablename__ = self.table_prefix + PROVIDES_TABLE
@@ -540,6 +544,8 @@ class SQLConnection(BaseConnection):
backref=orm.backref(
"provides",
cascade="all, delete-orphan"))
sa.Index(self.table_prefix + 'provides_build_id_idx',
build_id)
class BuildEventModel(Base):
__tablename__ = self.table_prefix + BUILD_EVENTS_TABLE
@@ -553,6 +559,8 @@ class SQLConnection(BaseConnection):
backref=orm.backref(
"build_events",
cascade="all, delete-orphan"))
sa.Index(self.table_prefix + 'build_event_build_id_idx',
build_id)
self.buildEventModel = BuildEventModel
self.zuul_build_event_table = self.buildEventModel.__table__