ఇండెక్స్ చేయని ఒక కాలమ్ మా డేటాబేస్ను ఎలా నాశనం చేసింది
ఒక చిన్న ఇండెక్స్ లేకపోవడం వల్ల 8 ms వేగంతో పనిచేసే API, 8 సెకన్ల দুঃస్వప్నంగా మారింది.
మేము ఒక ప్రధాన రిలీజ్ (release) ముందు లోడ్ టెస్ట్ (load test) నిర్వహించాము. 100 రికార్డులతో లోకల్ డెవలప్మెంట్ బాగానే పనిచేసింది. ఆ తర్వాత, ప్రొడక్షన్ సైజు డేటాలోని 1.5 మిలియన్ రోస్ (rows) పై 500 మంది వినియోగదారులను సిమ్యులేట్ (simulate) చేశాము.
ఫలితాలు చాలా దారుణంగా ఉన్నాయి:
- API రెస్పాన్స్ టైమ్స్ 45 ms నుండి 8,000 ms కి పెరిగాయి.
- డేటాబేస్ CPU 100% కి చేరుకుంది.
- కనెక్షన్ పూల్స్ (connection pools) పూర్తిగా ఖర్చయిపోయి, టైమ్ అవుట్ (timeout) ఎర్రర్స్ వచ్చాయి.
మేము స్లో-క్వరీ లాగ్ (slow-query log) తనిఖీ చేయగా, యూజర్ ID మరియు స్టేటస్ (status) ఆధారంగా ఆర్డర్ హిస్టరీని తీసుకునే ఒక ఎండ్పాయింట్ (endpoint) కనిపించింది.
PostgreSQLలో EXPLAIN ANALYZE రన్ చేయగా, అది 'Sequential Scan' అని చూపించింది. user_id పై ఇండెక్స్ లేకపోవడం వల్ల, ప్రతి రిక్వెస్ట్కు ఇంజిన్ మొత్తం 1.5 మిలియన్ రోస్ను చదవాల్సి వచ్చింది.
100 కన్కరెంట్ రిక్వెస్ట్లతో (concurrent requests), అది ఒకేసారి 150 మిలియన్ రోస్ను స్కాన్ చేసింది.
దీనికి పరిష్కారం కనుగొనడానికి కేవలం ఐదు నిమిషాలు పట్టింది.
user_id పై సాధారణ ఇండెక్స్ పెట్టడానికి బదులుగా, మేము (user_id, status, created_at DESC) పై ఒక కాంపోజిట్ ఇండెక్స్ (composite index) సృష్టించాము. దీనివల్ల డేటాబేస్:
user_idద్వారా ఫిల్టర్ చేయగలదు.statusద్వారా ఫిల్టర్ చేయగలదు.- కొత్త రోస్ను వెంటనే తిరిగి ఇవ్వగలదు.
- అదనపు సార్టింగ్ (sorting) దశలను దాటవేయగలదు.
ఆపరేషన్ జరుగుతున్నప్పుడు టేబుల్ లాక్ (lock) అవ్వకుండా ఉండటానికి మేము CREATE INDEX CONCURRENTLY ఉపయోగించాము.
పరిష్కారం తర్వాత:
- క్వరీ టైమ్ 8,150 ms నుండి 0.14 ms కి తగ్గింది.
- API లాటెన్సీ (latency) 8 సెకన్ల నుండి 12 ms కి పడిపోయింది.
- CPU వినియోగం 100% నుండి 8% కంటే తక్కువకు తగ్గింది.
నేర్చుకున్న పాఠాలు:
- లోకల్ టెస్టింగ్ తప్పుదారి పట్టించవచ్చు; 100 రోస్, మిలియన్ రోస్కు ప్రతిరూపం కాదు.
- మీ ఫారిన్ కీస్ (foreign keys) పై ఇండెక్స్ చేయండి—చాలా ORMలు దీనిని విస్మరిస్తాయి.
- మరిన్ని హార్డ్వేర్లను కొనే ముందు
EXPLAIN ANALYZEరన్ చేయండి. - మీరు నిజంగా రన్ చేసే క్వరీల ఆధారంగా ఇండెక్స్లను డిజైన్ చేయండి.
మొదట సర్వర్లను స్కేల్ చేయకండి. క్వరీలను స్కేల్ చేయండి.
