Skip to content

Commit 131738c

Browse files
authored
Merge pull request #58 from codervisor:copilot/implement-phase-2-structure
Phase 2: Optimize Prisma schema indexes for TimescaleDB time-series queries
2 parents 5796a87 + 274231d commit 131738c

File tree

3 files changed

+396
-7
lines changed

3 files changed

+396
-7
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
-- Migration: Add TimescaleDB-optimized composite indexes for agent_events
2+
-- Phase 2 of Database Architecture Specification (specs/20251031/001-database-architecture)
3+
--
4+
-- This migration adds composite indexes for optimal TimescaleDB query performance:
5+
-- 1. session_id + timestamp (DESC) - for session timeline queries
6+
-- 2. project_id + timestamp (DESC) - for project timeline queries
7+
-- 3. GIN index on data JSONB field - for flexible JSON queries
8+
--
9+
-- These indexes complement the existing single-column indexes and improve
10+
-- performance for time-range queries filtered by session or project.
11+
12+
-- Drop existing single-column indexes that will be replaced by composite indexes
13+
DROP INDEX IF EXISTS "agent_events_session_id_idx";
14+
DROP INDEX IF EXISTS "agent_events_project_id_idx";
15+
16+
-- Create composite index for session timeline queries
17+
-- Optimizes: SELECT * FROM agent_events WHERE session_id = ? AND timestamp > ?
18+
CREATE INDEX "agent_events_session_id_timestamp_idx" ON "agent_events"("session_id", "timestamp" DESC);
19+
20+
-- Create composite index for project timeline queries
21+
-- Optimizes: SELECT * FROM agent_events WHERE project_id = ? AND timestamp > ?
22+
CREATE INDEX "agent_events_project_id_timestamp_idx" ON "agent_events"("project_id", "timestamp" DESC);
23+
24+
-- Create GIN index for JSONB data field
25+
-- Optimizes: SELECT * FROM agent_events WHERE data @> '{"key": "value"}'::jsonb
26+
CREATE INDEX "agent_events_data_idx" ON "agent_events" USING GIN ("data");
27+
28+
-- Note: The `data` field uses the default GIN operator class (jsonb_ops),
29+
-- which supports containment queries (@>, <@) and existence queries (?, ?|, ?&).
30+
-- Alternative: jsonb_path_ops uses less storage but only supports @> operator.
31+
-- The default is chosen for maximum query flexibility.

prisma/schema.prisma

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,20 @@ model ChatMessage {
303303
// ============================================================================
304304

305305
// Agent Events - Individual actions (TimescaleDB hypertable)
306+
//
307+
// NOTE: This table is converted to a TimescaleDB hypertable for time-series optimization.
308+
// The conversion is performed by scripts/enable-timescaledb.sql which:
309+
// - Creates a hypertable partitioned by timestamp (1-day chunks)
310+
// - Enables compression after 7 days (70-90% storage reduction)
311+
// - Sets up automatic retention policy (1 year)
312+
// - Creates continuous aggregates for hourly and daily statistics
313+
//
314+
// Performance characteristics:
315+
// - Write throughput: 50-100K events/sec
316+
// - Query latency: 30-50ms P95 for time-range queries
317+
// - Storage: 200-500 bytes per event after compression
318+
//
319+
// See: specs/20251031/001-database-architecture/README.md for details
306320
model AgentEvent {
307321
id String @id @default(uuid()) @db.Uuid
308322
timestamp DateTime @db.Timestamptz
@@ -333,13 +347,15 @@ model AgentEvent {
333347
session ChatSession @relation(fields: [sessionId], references: [sessionId], onDelete: Cascade)
334348
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
335349
336-
@@index([timestamp(sort: Desc)])
337-
@@index([sessionId])
338-
@@index([agentId])
339-
@@index([eventType])
340-
@@index([projectId])
341-
@@index([tags])
342-
@@index([severity])
350+
// Indexes optimized for TimescaleDB time-series queries
351+
@@index([timestamp(sort: Desc)]) // Primary time-series index
352+
@@index([sessionId, timestamp(sort: Desc)]) // Session timeline queries (composite)
353+
@@index([projectId, timestamp(sort: Desc)]) // Project timeline queries (composite)
354+
@@index([agentId]) // Filter by agent type
355+
@@index([eventType]) // Filter by event type
356+
@@index([tags]) // Array index for tag filtering
357+
@@index([severity]) // Filter by severity level
358+
@@index([data]) // GIN index for JSONB field queries (created in migration)
343359
@@map("agent_events")
344360
}
345361

0 commit comments

Comments
 (0)