ಇಂಡೆಕ್ಸ್ ಮಾಡದ ಒಂದು ಕಾಲಂ ನಮ್ಮ ಡೇಟಾಬೇಸ್ ಅನ್ನು ಹೇಗೆ ಹಾಳುಮಾಡಿತು
ಒಂದು ಸಣ್ಣ ಇಂಡೆಕ್ಸ್ ಇಲ್ಲದಿರುವುದು 8 ms ವೇಗದ API ಅನ್ನು 8 ಸೆಕೆಂಡುಗಳ ದುಸ್ವಪ್ನವನ್ನಾಗಿ ಮಾಡಿತು.
ನಾವು ಪ್ರಮುಖ ಬಿಡುಗಡೆಯ ಮೊದಲು ಲೋಡ್ ಟೆಸ್ಟ್ (load test) ನಡೆಸಿದೆವು. 100 ರೆಕಾರ್ಡ್ಗಳೊಂದಿಗೆ ಸ್ಥಳೀಯ ಅಭಿವೃದ್ಧಿ (Local development) ಸರಿಯಾಗಿ ಕೆಲಸ ಮಾಡಿತು. ನಂತರ ನಾವು ಪ್ರೊಡಕ್ಷನ್ ಗಾತ್ರದ ಡೇಟಾದಲ್ಲಿ 1.5 ಮಿಲಿಯನ್ ಸಾಲುಗಳ (rows) ಮೇಲೆ 500 ಬಳಕೆದಾರರನ್ನು ಸಿಮ್ಯುಲೇಟ್ ಮಾಡಿದೆವು.
ಫಲಿತಾಂಶಗಳು ಕೆಟ್ಟದಾಗಿದ್ದವು:
- API ರೆಸ್ಪಾನ್ಸ್ ಸಮಯವು 45 ms ನಿಂದ 8,000 ms ಗೆ ಏರಿತು.
- ಡೇಟಾಬೇಸ್ CPU 100 % ತಲುಪಿತು.
- ಕನೆಕ್ಷನ್ ಪೂಲ್ಗಳು (Connection pools) ಖಾಲಿಯಾದವು, ಇದರಿಂದ ಟೈಮೌಟ್ ದೋಷಗಳು (timeout errors) ಉಂಟಾದವು.
ನಾವು ಸ್ಲೋ-ಕ್ವೆರಿ ಲಾಗ್ (slow-query log) ಪರಿಶೀಲಿಸಿದಾಗ, ಬಳಕೆದಾರರ ID ಮತ್ತು status ಮೂಲಕ ಆರ್ಡರ್ ಇತಿಹಾಸವನ್ನು ಪಡೆಯುವ ಎಂಡ್ಪಾಯಿಂಟ್ ಅನ್ನು ಪತ್ತೆಹಚ್ಚಿದೆವು.
PostgreSQL ನಲ್ಲಿ EXPLAIN ANALYZE ಅನ್ನು ರನ್ ಮಾಡಿದಾಗ 'Sequential Scan' ಕಂಡುಬಂದಿತು. user_id ಮೇಲೆ ಇಂಡೆಕ್ಸ್ ಇಲ್ಲದ ಕಾರಣ, ಇಂಜಿನ್ ಪ್ರತಿ ವಿನಂತಿಗೂ (request) ಎಲ್ಲಾ 1.5 ಮಿಲಿಯನ್ ಸಾಲುಗಳನ್ನು ಓದಬೇಕಾಯಿತು.
100 ಏಕಕಾಲಿಕ ವಿನಂತಿಗಳೊಂದಿಗೆ (concurrent requests), ಅದು ಒಂದೇ ಬಾರಿಗೆ 150 ಮಿಲಿಯನ್ ಸಾಲುಗಳನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಿತು.
ಇದನ್ನು ಸರಿಪಡಿಸಲು ಐದು ನಿಮಿಷಗಳು ಬೇಕಾದವು.
user_id ಮೇಲೆ ಸರಳ ಇಂಡೆಕ್ಸ್ ಮಾಡುವ ಬದಲು, ನಾವು (user_id, status, created_at DESC) ಮೇಲೆ ಕಾಂಪೋಸಿಟ್ ಇಂಡೆಕ್ಸ್ (composite index) ರಚಿಸಿದೆವು. ಇದು ಡೇಟಾಬೇಸ್ಗೆ ಈ ಕೆಳಗಿನವುಗಳನ್ನು ಮಾಡಲು ಅನುವು ಮಾಡಿಕೊಟ್ಟಿತು:
user_idಮೂಲಕ ಫಿಲ್ಟರ್ ಮಾಡಲು.statusಮೂಲಕ ಫಿಲ್ಟರ್ ಮಾಡಲು.- ಹೊಸ ಸಾಲುಗಳನ್ನು ತಕ್ಷಣವೇ ಹಿಂತಿರುಗಿಸಲು.
- ಹೆಚ್ಚುವರಿ ಸಾರ್ಟಿಂಗ್ ಹಂತಗಳನ್ನು ಬಿಟ್ಟುಬಿಡಲು.
ನಾವು CREATE INDEX CONCURRENTLY ಅನ್ನು ಬಳಸಿದೆವು, ಇದರಿಂದ ಕಾರ್ಯಾಚರಣೆಯ ಸಮಯದಲ್ಲಿ ಟೇಬಲ್ ಅನ್ಲಾಕ್ ಆಗಿಯೇ ಇತ್ತು.
ಸರಿಪಡಿಸಿದ ನಂತರ:
- ಕ್ವೆರಿ ಸಮಯವು 8,150 ms ನಿಂದ 0.14 ms ಗೆ ಇಳಿಯಿತು.
- API ಲೇಟೆನ್ಸಿ (latency) 8 ಸೆಕೆಂಡುಗಳಿಂದ 12 ms ಗೆ ಇಳಿಯಿತು.
- CPU ಬಳಕೆ 100 % ನಿಂದ 8 % ಕ್ಕಿಂತ ಕಡಿಮೆಗೆ ಇಳಿಯಿತು.
ಕಲಿತ ಪಾಠಗಳು:
- ಸ್ಥಳೀಯ ಪರೀಕ್ಷೆಯು (Local testing) ದಾರಿ ತಪ್ಪಿಸಬಹುದು; 100 ಸಾಲುಗಳು ಮಿಲಿಯನ್ ಸಾಲುಗಳನ್ನು ಪ್ರತಿನಿಧಿಸುವುದಿಲ್ಲ.
- ನಿಮ್ಮ ಫಾರಿನ್ ಕೀಗಳನ್ನು (foreign keys) ಇಂಡೆಕ್ಸ್ ಮಾಡಿ—ಹೆಚ್ಚಿನ ORMಗಳು ಇದನ್ನು ಬಿಟ್ಟುಬಿಡುತ್ತವೆ.
- ಹೆಚ್ಚಿನ ಹಾರ್ಡ್ವೇರ್ ಖರೀದಿಸುವ ಮೊದಲು
EXPLAIN ANALYZEಅನ್ನು ರನ್ ಮಾಡಿ. - ನೀವು ವಾಸ್ತವವಾಗಿ ರನ್ ಮಾಡುವ ಕ್ವೆರಿಗಳ ಆಧಾರದ ಮೇಲೆ ಇಂಡೆಕ್ಸ್ಗಳನ್ನು ವಿನ್ಯಾಸಗೊಳಿಸಿ.
ಮೊದಲು ಸರ್ವರ್ಗಳನ್ನು ಸ್ಕೇಲ್ ಮಾಡಬೇಡಿ. ಕ್ವೆರಿಗಳನ್ನು ಸ್ಕೇಲ್ ಮಾಡಿ.
