← back to Handbag Auth Nextjs
auction-viewer/db-optimization.sql
170 lines
-- ============================================
-- Database Optimization Script
-- LUXVAULT Auction Viewer
-- ============================================
-- Enable Write-Ahead Logging for better concurrency
PRAGMA journal_mode = WAL;
-- Set synchronous mode to NORMAL for better performance
PRAGMA synchronous = NORMAL;
-- Increase cache size (64MB)
PRAGMA cache_size = -64000;
-- Use memory for temporary storage
PRAGMA temp_store = MEMORY;
-- Enable memory-mapped I/O (30GB)
PRAGMA mmap_size = 30000000000;
-- ============================================
-- Create Performance Indexes
-- ============================================
-- Index on search_term (brand) - frequently filtered
CREATE INDEX IF NOT EXISTS idx_auctions_search_term
ON auctions(search_term);
-- Index on created_at - for chronological sorting
CREATE INDEX IF NOT EXISTS idx_auctions_created_at
ON auctions(created_at DESC);
-- Index on current_price - for price range queries
CREATE INDEX IF NOT EXISTS idx_auctions_current_price
ON auctions(current_price);
-- Index on auction_house - for filtering
CREATE INDEX IF NOT EXISTS idx_auctions_auction_house
ON auctions(auction_house);
-- Index on end_date - for time-based queries
CREATE INDEX IF NOT EXISTS idx_auctions_end_date
ON auctions(end_date);
-- Index on data_hash - for deduplication
CREATE INDEX IF NOT EXISTS idx_auctions_data_hash
ON auctions(data_hash);
-- Composite index for common query patterns
CREATE INDEX IF NOT EXISTS idx_auctions_brand_price
ON auctions(search_term, current_price, created_at DESC);
-- Composite index for deal hunting
CREATE INDEX IF NOT EXISTS idx_auctions_deals
ON auctions(estimate_low, current_price)
WHERE current_price > 0 AND estimate_low > 0;
-- Index for auction ending soon queries
CREATE INDEX IF NOT EXISTS idx_auctions_ending_soon
ON auctions(end_date, current_price)
WHERE end_date IS NOT NULL;
-- ============================================
-- Analyze Tables for Query Optimizer
-- ============================================
ANALYZE auctions;
ANALYZE auctions_fts;
-- ============================================
-- Archive Old Data (optional)
-- ============================================
-- Create archive table if it doesn't exist
CREATE TABLE IF NOT EXISTS auctions_archive (
id INTEGER PRIMARY KEY AUTOINCREMENT,
auction_id TEXT UNIQUE,
title TEXT,
auction_house TEXT,
current_price REAL,
estimate_low REAL,
estimate_high REAL,
end_date TEXT,
lot_number TEXT,
url TEXT,
search_term TEXT,
created_at TIMESTAMP,
archived_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Index on archive table
CREATE INDEX IF NOT EXISTS idx_archive_created_at
ON auctions_archive(created_at);
CREATE INDEX IF NOT EXISTS idx_archive_archived_at
ON auctions_archive(archived_at);
-- ============================================
-- Vacuum and Optimize
-- ============================================
-- Rebuild database to reclaim space and optimize
-- VACUUM;
-- Note: Uncomment VACUUM command and run manually during low-traffic periods
-- ============================================
-- Statistics
-- ============================================
-- Check index usage
SELECT
name,
tbl_name,
CASE
WHEN sql LIKE '%UNIQUE%' THEN 'UNIQUE'
ELSE 'INDEX'
END as type
FROM sqlite_master
WHERE type = 'index'
AND tbl_name = 'auctions'
ORDER BY name;
-- Check table size
SELECT
name,
(pgsize * pgcount) / 1024.0 / 1024.0 as size_mb
FROM dbstat
WHERE name = 'auctions';
-- ============================================
-- Query Performance Testing
-- ============================================
-- Test query plan for brand filtering
EXPLAIN QUERY PLAN
SELECT * FROM auctions
WHERE search_term = 'Hermes Birkin'
ORDER BY created_at DESC
LIMIT 50;
-- Test query plan for price range
EXPLAIN QUERY PLAN
SELECT * FROM auctions
WHERE current_price BETWEEN 5000 AND 20000
ORDER BY current_price ASC
LIMIT 50;
-- Test query plan for full-text search
EXPLAIN QUERY PLAN
SELECT a.* FROM auctions a
WHERE a.id IN (
SELECT rowid FROM auctions_fts
WHERE auctions_fts MATCH 'birkin leather'
)
LIMIT 50;
-- Test query plan for best deals
EXPLAIN QUERY PLAN
SELECT *,
CASE
WHEN estimate_low > 0 AND current_price > 0
THEN ((estimate_low - current_price) / estimate_low * 100)
ELSE 0
END as savings_percent
FROM auctions
WHERE current_price > 0 AND estimate_low > 0
ORDER BY savings_percent DESC
LIMIT 50;