Compare commits

...

3 Commits

Author SHA1 Message Date
LearningCircuit b3d7b5a6d5 Merge branch 'main' into fix/database-indexes-performance 2026-02-21 23:13:16 +01:00
LearningCircuit 90f41c42f0 test: add tests for database index definitions 2026-02-06 03:10:47 +01:00
LearningCircuit da0cc2864e perf: add database indexes for query performance
Add indexes to ResearchHistory and ResearchTask models for frequently
queried columns to improve database query performance:

ResearchHistory:
- Add index on mode column (filtering by research mode)
- Add index on status column (filtering by status)
- Add index on created_at column (time-range queries)
- Add composite index on (status, created_at) for status listing
- Add composite index on (mode, status) for mode filtering

ResearchTask:
- Add index on status column (filtering by status)
- Add index on created_at column (time-range queries)
- Add composite index on (status, created_at) for task listing
- Add composite index on (priority, status) for priority-based queries

These indexes will significantly improve query performance for:
- History page listing
- Metrics dashboard aggregations
- Status filtering operations
2026-02-05 00:05:03 +01:00
2 changed files with 81 additions and 5 deletions
@@ -34,14 +34,14 @@ class ResearchTask(Base):
title = Column(String(500), nullable=False)
description = Column(Text)
status = Column(
String(50), default="pending"
String(50), default="pending", index=True
) # pending, in_progress, completed, failed
priority = Column(Integer, default=0) # Higher number = higher priority
tags = Column(JSON) # List of tags for categorization
research_metadata = Column(JSON) # Flexible field for additional data
# Timestamps
created_at = Column(UtcDateTime, default=utcnow())
created_at = Column(UtcDateTime, default=utcnow(), index=True)
updated_at = Column(UtcDateTime, default=utcnow(), onupdate=utcnow())
started_at = Column(UtcDateTime)
completed_at = Column(UtcDateTime)
@@ -61,6 +61,12 @@ class ResearchTask(Base):
"Report", back_populates="research_task", cascade="all, delete-orphan"
)
# Indexes for performance on frequently queried columns
__table_args__ = (
Index("idx_research_task_status_created", "status", "created_at"),
Index("idx_research_task_priority_status", "priority", "status"),
)
def __repr__(self):
return f"<ResearchTask(title='{self.title}', status='{self.status}')>"
@@ -214,11 +220,11 @@ class ResearchHistory(Base):
# The search query.
query = Column(Text, nullable=False)
# The mode of research (e.g., 'quick_summary', 'detailed_report').
mode = Column(Text, nullable=False)
mode = Column(Text, nullable=False, index=True)
# Current status of the research.
status = Column(Text, nullable=False)
status = Column(Text, nullable=False, index=True)
# The timestamp when the research started.
created_at = Column(Text, nullable=False)
created_at = Column(Text, nullable=False, index=True)
# The timestamp when the research was completed.
completed_at = Column(Text)
# Duration of the research in seconds.
@@ -243,6 +249,12 @@ class ResearchHistory(Base):
cascade="all, delete-orphan",
)
# Indexes for performance on frequently queried columns
__table_args__ = (
Index("idx_research_history_status_created", "status", "created_at"),
Index("idx_research_history_mode_status", "mode", "status"),
)
def __repr__(self):
return f"<ResearchHistory(query='{self.query[:50]}...', status={self.status})>"
+64
View File
@@ -0,0 +1,64 @@
"""Tests for database index definitions on research models."""
from local_deep_research.database.models.research import (
ResearchHistory,
ResearchTask,
)
class TestResearchTaskIndexes:
def test_status_column_indexed(self):
status_col = ResearchTask.__table__.columns["status"]
assert status_col.index is True
def test_created_at_column_indexed(self):
created_col = ResearchTask.__table__.columns["created_at"]
assert created_col.index is True
def test_composite_indexes_defined(self):
index_names = [idx.name for idx in ResearchTask.__table__.indexes]
assert "idx_research_task_status_created" in index_names
assert "idx_research_task_priority_status" in index_names
def test_composite_index_status_created_columns(self):
indexes = {idx.name: idx for idx in ResearchTask.__table__.indexes}
idx = indexes["idx_research_task_status_created"]
col_names = [col.name for col in idx.columns]
assert col_names == ["status", "created_at"]
def test_composite_index_priority_status_columns(self):
indexes = {idx.name: idx for idx in ResearchTask.__table__.indexes}
idx = indexes["idx_research_task_priority_status"]
col_names = [col.name for col in idx.columns]
assert col_names == ["priority", "status"]
class TestResearchHistoryIndexes:
def test_status_column_indexed(self):
status_col = ResearchHistory.__table__.columns["status"]
assert status_col.index is True
def test_mode_column_indexed(self):
mode_col = ResearchHistory.__table__.columns["mode"]
assert mode_col.index is True
def test_created_at_column_indexed(self):
created_col = ResearchHistory.__table__.columns["created_at"]
assert created_col.index is True
def test_composite_indexes_defined(self):
index_names = [idx.name for idx in ResearchHistory.__table__.indexes]
assert "idx_research_history_status_created" in index_names
assert "idx_research_history_mode_status" in index_names
def test_composite_index_status_created_columns(self):
indexes = {idx.name: idx for idx in ResearchHistory.__table__.indexes}
idx = indexes["idx_research_history_status_created"]
col_names = [col.name for col in idx.columns]
assert col_names == ["status", "created_at"]
def test_composite_index_mode_status_columns(self):
indexes = {idx.name: idx for idx in ResearchHistory.__table__.indexes}
idx = indexes["idx_research_history_mode_status"]
col_names = [col.name for col in idx.columns]
assert col_names == ["mode", "status"]