fix: add composite index on event_callback (conversation_id, status, event_kind) (#14630)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
Ash Clarke
2026-06-04 10:15:25 -04:00
committed by GitHub
co-authored by openhands
parent 73d1d9a1c9
commit 88291a5980
2 changed files with 51 additions and 1 deletions
@@ -0,0 +1,42 @@
"""Add composite index on event_callback for execute_callbacks query
Revision ID: 010
Revises: 009
Create Date: 2026-06-03
The execute_callbacks query filters on (status, event_kind, conversation_id)
but none of these columns were indexed, causing full table scans on every
event dispatch. This index directly covers that query.
CREATE INDEX CONCURRENTLY is used to avoid locking the table during deployment.
"""
from typing import Sequence
from alembic import op
revision: str = '010'
down_revision: str | None = '009'
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
with op.get_context().autocommit_block():
op.create_index(
'ix_event_callback_conversation_id_status_event_kind',
'event_callback',
['conversation_id', 'status', 'event_kind'],
postgresql_concurrently=True,
if_not_exists=True,
)
def downgrade() -> None:
with op.get_context().autocommit_block():
op.drop_index(
'ix_event_callback_conversation_id_status_event_kind',
table_name='event_callback',
postgresql_concurrently=True,
if_exists=True,
)
@@ -11,7 +11,7 @@ from typing import AsyncGenerator
from uuid import UUID, uuid4
from fastapi import Request
from sqlalchemy import Enum, String, and_, func, select
from sqlalchemy import Enum, Index, String, and_, func, select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Mapped, mapped_column
@@ -47,6 +47,14 @@ _logger = logging.getLogger(__name__)
class StoredEventCallback(Base):
__tablename__ = 'event_callback'
__table_args__ = (
Index(
'ix_event_callback_conversation_id_status_event_kind',
'conversation_id',
'status',
'event_kind',
),
)
id: Mapped[UUID] = mapped_column(primary_key=True)
conversation_id: Mapped[UUID | None] = mapped_column(nullable=True)