ஒரு இன்டெக்ஸ் செய்யப்படாத Column எங்களது Database-ஐ எவ்வாறு அழித்தது

ஒரு சிறிய இன்டெக்ஸ் விடுபட்டது, 8 ms வேகத்தில் இயங்கிய API-ஐ 8 வினாடி nightmare-ஆக மாற்றியது.

ஒரு முக்கிய வெளியீட்டிற்கு (major release) முன்னதாக நாங்கள் ஒரு load test செய்தோம். உள்ளூர் மேம்பாட்டுச் சூழலில் (Local development) 100 வரிசைகள் (rows) நன்றாகச் செயல்பட்டன. Staging சூழலில், 1.5 மில்லியன் வரிசைகளைக் கொண்டு 500 பயனர்களைச் செயற்கையாக உருவாக்கினோம் (simulated).

அனைத்தும் செயலிழந்தன.

  • API response நேரங்கள் 45 ms-லிருந்து 8,000 ms-ஆக உயர்ந்தன.
  • Database CPU 100 % எட்டியது.
  • Connection pools தீர்ந்துவிட்டன.
  • Requests காலாவதியானன (timed out).

இதற்குக் காரணம் user_id மற்றும் status மூலம் ஆர்டர் வரலாற்றைப் (order history) பெறும் ஒரு எளிய query தான்.

PostgreSQL-இல் EXPLAIN ANALYZE செய்தபோது, அது ஒரு Sequential Scan என்பதைக் காட்டியது. user_id-இல் இன்டெக்ஸ் இல்லாததால், ஒவ்வொரு கோரிக்கைக்கும் (request) இன்ஜின் அனைத்து 1.5 மில்லியன் வரிசைகளையும் வாசித்தது.

100 ஒரே நேரத்தில் வரும் கோரிக்கைகளின் போது (concurrent requests), தரவுத்தளம் ஒரே நேரத்தில் 150 மில்லியன் வரிசைகளை ஸ்கேன் செய்தது.

இதைச் சரிசெய்ய ஐந்து நிமிடங்கள் ஆனது. அட்டவணை (table) தொடர்ந்து இயங்கிக் கொண்டிருப்பதை உறுதி செய்ய, CREATE INDEX CONCURRENTLY முறையைப் பயன்படுத்தி (user_id, status, created_at DESC) ஆகியவற்றின் மீது ஒரு composite index-ஐ உருவாக்கினோம்.

முடிவுகள்:

  • Query நேரம் 8,150 ms-லிருந்து 0.14 ms-ஆகக் குறைந்தது.
  • API latency 8 வினாடிகளிலிருந்து 12 ms-ஆகக் குறைந்தது.
  • CPU பயன்பாடு 100 %-லிருந்து 8 %-க்கும் குறைவாகக் குறைந்தது.

கற்றுக்கொண்ட பாடங்கள்:

  • உள்ளூர் சோதனைகள் தவறாக வழிநடத்தலாம்; 100 வரிசைகள் என்பது ஒரு மில்லியன் வரிசைகளுக்குப் பதிலாகாது.
  • Foreign keys-களுக்கு இன்டெக்ஸ் செய்யுங்கள்—பெரும்பாலான ORMs இதைத் தவிர்க்கின்றன.
  • EXPLAIN ANALYZE செய்யுங்கள்; தரவுத்தளமே சிக்கலைக் காட்டிவிடும்.
  • கூடுதல் வன்பொருள்களை (hardware) வாங்குவதற்கு முன், queries-களை மேம்படுத்துங்கள் (optimize).

முதலில் சர்வர்களை (servers) பெரிதாக்காதீர்கள். Queries-களை மேம்படுத்துங்கள்.

ஆதாரம்: https://dev.to/mia_keller_ffd2584c046ecb/how-an-unindexed-column-silently-killed-our-database-under-load-and-the-5-minute-fix-m32