diff --git a/src/remote/optimization.ts b/src/remote/optimization.ts index f2d7d46..7fbb940 100644 --- a/src/remote/optimization.ts +++ b/src/remote/optimization.ts @@ -28,6 +28,7 @@ export const LiveQueryOptimization = z.discriminatedUnion("state", [ costReductionPercentage: z.number(), indexRecommendations: z.array(IndexRecommendation), indexesUsed: z.array(z.string()), + consideredIndexes: z.array(IndexRecommendation).optional(), explainPlan: z.custom(), optimizedExplainPlan: z.custom(), }), @@ -35,6 +36,7 @@ export const LiveQueryOptimization = z.discriminatedUnion("state", [ state: z.literal("no_improvement_found"), cost: z.number(), indexesUsed: z.array(z.string()), + consideredIndexes: z.array(IndexRecommendation).optional(), explainPlan: z.custom(), }), z.object({ state: z.literal("timeout") }), diff --git a/src/remote/query-optimizer.ts b/src/remote/query-optimizer.ts index 39e29db..cd69923 100644 --- a/src/remote/query-optimizer.ts +++ b/src/remote/query-optimizer.ts @@ -408,16 +408,19 @@ export class QueryOptimizer extends EventEmitter { Math.abs(percentageReduction), ); if (costReductionPercentage < MINIMUM_COST_CHANGE_PERCENTAGE) { + const consideredIndexes = mapConsideredIndexes(result); this.onNoImprovements( recent, result.baseCost, indexesUsed, + consideredIndexes, explainPlan, ); return { state: "no_improvement_found", cost: result.baseCost, indexesUsed, + consideredIndexes, explainPlan, }; } else { @@ -429,6 +432,7 @@ export class QueryOptimizer extends EventEmitter { costReductionPercentage, indexRecommendations, indexesUsed, + consideredIndexes: mapConsideredIndexes(result), explainPlan, optimizedExplainPlan: result.explainPlan, }; @@ -444,6 +448,7 @@ export class QueryOptimizer extends EventEmitter { recent: OptimizedQuery, cost: number, indexesUsed: string[], + consideredIndexes: IndexRecommendation[], explainPlan: PostgresExplainStage, ) { this.emit( @@ -452,6 +457,7 @@ export class QueryOptimizer extends EventEmitter { state: "no_improvement_found", cost, indexesUsed, + consideredIndexes, explainPlan, }), ); @@ -512,6 +518,7 @@ export class QueryOptimizer extends EventEmitter { costReductionPercentage, indexRecommendations, indexesUsed, + consideredIndexes: mapConsideredIndexes(result), explainPlan, optimizedExplainPlan: result.explainPlan, }; @@ -582,6 +589,12 @@ function mapIndexRecommandations( }); } +function mapConsideredIndexes( + result: Extract, +): IndexRecommendation[] { + return Array.from(result.triedIndexes.values()); +} + type PercentageDifference = number; export function costDifferencePercentage(