diff --git a/performance-indexes.sql b/performance-indexes.sql new file mode 100644 index 0000000..482a485 --- /dev/null +++ b/performance-indexes.sql @@ -0,0 +1,26 @@ +-- Performance indexes for server-recommend +-- Run these on the cloud-instances-db D1 database + +-- instance_types: Optimize filtering by provider and specs +CREATE INDEX IF NOT EXISTS idx_instance_types_provider_specs +ON instance_types(provider_id, vcpu, memory_mb); + +-- pricing: Optimize joins with instance_types and regions +CREATE INDEX IF NOT EXISTS idx_pricing_instance_region +ON pricing(instance_type_id, region_id); + +-- pricing: Optimize price-based sorting +CREATE INDEX IF NOT EXISTS idx_pricing_price +ON pricing(monthly_price_retail, monthly_price_krw); + +-- regions: Optimize region code lookups +CREATE INDEX IF NOT EXISTS idx_regions_codes +ON regions(region_code, country_code); + +-- vps_benchmarks: Optimize spec-based lookups +CREATE INDEX IF NOT EXISTS idx_vps_benchmarks_specs +ON vps_benchmarks(vcpu, memory_gb, provider_name); + +-- vps_benchmarks: Optimize performance queries +CREATE INDEX IF NOT EXISTS idx_vps_benchmarks_performance +ON vps_benchmarks(geekbench_single DESC, monthly_price_usd); diff --git a/src/index.ts b/src/index.ts index 9fbc627..50af0be 100644 --- a/src/index.ts +++ b/src/index.ts @@ -997,9 +997,23 @@ async function handleRecommend( const bandwidthEstimate = estimateBandwidth(body.expected_users, body.use_case, body.traffic_pattern); console.log(`[Recommend] Bandwidth estimate: ${bandwidthEstimate.monthly_tb >= 1 ? bandwidthEstimate.monthly_tb + ' TB' : bandwidthEstimate.monthly_gb + ' GB'}/month (${bandwidthEstimate.category})`); - // Phase 2: Query candidate servers (depends on minMemoryMb, minVcpu, bandwidth) - const candidates = await queryCandidateServers(env.DB, body, minMemoryMb, minVcpu, bandwidthEstimate, lang); + // Estimate specs for VPS benchmark query (doesn't need exact candidates) + const estimatedCores = minVcpu || 2; + const estimatedMemory = minMemoryMb ? Math.ceil(minMemoryMb / 1024) : 4; + const defaultProviders = bandwidthEstimate?.category === 'very_heavy' ? ['Linode'] : ['Linode', 'Vultr']; + + // Phase 2: Query candidate servers and VPS benchmarks in parallel + const [candidates, vpsBenchmarks] = await Promise.all([ + queryCandidateServers(env.DB, body, minMemoryMb, minVcpu, bandwidthEstimate, lang), + queryVPSBenchmarksBatch(env.DB, estimatedCores, estimatedMemory, defaultProviders).catch((err: unknown) => { + const message = err instanceof Error ? err.message : String(err); + console.warn('[Recommend] VPS benchmarks unavailable:', message); + return [] as VPSBenchmark[]; + }), + ]); + console.log('[Recommend] Candidate servers:', candidates.length); + console.log('[Recommend] VPS benchmark data points:', vpsBenchmarks.length); if (candidates.length === 0) { return jsonResponse( @@ -1013,28 +1027,9 @@ async function handleRecommend( ); } - // Calculate average specs from candidates for VPS benchmark queries - const avgCores = Math.round( - candidates.reduce((sum, s) => sum + s.vcpu, 0) / candidates.length - ); - const avgMemory = Math.round( - candidates.reduce((sum, s) => sum + s.memory_gb, 0) / candidates.length - ); - // Use initially fetched benchmark data (already filtered by tech stack) const benchmarkData = benchmarkDataAll; - // Get unique providers from candidates - const providers = [...new Set(candidates.map((c) => c.provider_name))]; - console.log('[Recommend] Providers:', providers); - - // Query VPS benchmarks using consolidated single query (includes provider-specific and spec-based matching) - const vpsBenchmarks = await queryVPSBenchmarksBatch(env.DB, avgCores, avgMemory, providers).catch(err => { - console.warn('[Recommend] VPS benchmark data unavailable:', err.message); - return [] as VPSBenchmark[]; - }); - console.log('[Recommend] VPS benchmark data points:', vpsBenchmarks.length); - // Use OpenAI GPT-4o-mini to analyze and recommend (techSpecs already queried above) const aiResult = await getAIRecommendations( env,