ਇੱਕ ਬਿਨਾਂ ਇੰਡੈਕਸ ਵਾਲੇ ਕਾਲਮ ਨੇ ਸਾਡੇ ਡਾਟਾਬੇਸ ਨੂੰ ਕਿਵੇਂ ਬਰਬਾਦ ਕਰ ਦਿੱਤਾ

ਇੱਕ ਗੁੰਮ ਹੋਇਆ ਇੰਡੈਕਸ 8 ਮਿਲੀਸੈਕਿੰਡ ਦੀ API ਨੂੰ 8-ਸੈਕਿੰਡ ਦੇ ਡਰਾਉਣੇ ਸੁਪਨੇ ਵਿੱਚ ਬਦਲ ਦਿੱਤਾ।

ਅਸੀਂ ਇੱਕ ਵੱਡੀ ਰਿਲੀਜ਼ ਤੋਂ ਪਹਿਲਾਂ ਲੋਡ ਟੈਸਟ (load test) ਕੀਤਾ। ਲੋਕਲ ਡਿਵੈਲਪਮੈਂਟ ਵਿੱਚ 100 ਰੋਅਜ਼ (rows) ਦਾ ਕੋਈ ਮਸਲਾ ਨਹੀਂ ਸੀ। ਸਟੇਜਿੰਗ (staging) ਵਿੱਚ ਅਸੀਂ 1.5 ਮਿਲੀਅਨ ਰੋਅਜ਼ 'ਤੇ 500 ਯੂਜ਼ਰਸ ਦਾ ਸਿਮੂਲੇਸ਼ਨ ਕੀਤਾ।

ਸਭ ਕੁਝ ਵਿਗੜ ਗਿਆ।

  • API ਰਿਸਪਾਂਸ ਟਾਈਮ 45 ਮਿਲੀਸੈਕਿੰਡ ਤੋਂ ਵਧ ਕੇ 8,000 ਮਿਲੀਸੈਕਿੰਡ ਹੋ ਗਿਆ।
  • ਡਾਟਾਬੇਸ CPU 100% ਤੱਕ ਪਹੁੰਚ ਗਿਆ।
  • ਕਨੈਕਸ਼ਨ ਪੂਲ (connection pools) ਖਤਮ ਹੋ ਗਏ।
  • ਰਿਕੁਐਸਟਾਂ ਟਾਈਮ ਆਊਟ ਹੋ ਗਈਆਂ।

ਇਸਦਾ ਮੁੱਖ ਕਾਰਨ ਇੱਕ ਸਧਾਰਨ ਕੁਐਰੀ (query) ਸੀ ਜੋ user_id ਅਤੇ status ਰਾਹੀਂ ਆਰਡਰ ਹਿਸਟਰੀ ਲਿਆ ਰਹੀ ਸੀ।

PostgreSQL 'ਤੇ EXPLAIN ANALYZE ਚਲਾਉਣ 'ਤੇ ਇੱਕ ਸੀਕੁਐਂਸ਼ੀਅਲ ਸਕੈਨ (Sequential Scan) ਦਿਖਾਈ ਦਿੱਤਾ। user_id 'ਤੇ ਕੋਈ ਇੰਡੈਕਸ ਨਾ ਹੋਣ ਕਰਕੇ, ਇੰਜਣ ਹਰ ਰਿਕੁਐਸ ਲਈ ਸਾਰੀਆਂ 1.5 ਮਿਲੀਅਨ ਰੋਅਜ਼ ਨੂੰ ਪੜ੍ਹ ਰਿਹਾ ਸੀ।

100 ਕੰਕਰੈਂਟ (concurrent) ਰਿਕੁਐਸਟਾਂ 'ਤੇ ਡਾਟਾਬੇਸ ਨੇ ਇੱਕੋ ਵਾਰ ਵਿੱਚ 150 ਮਿਲੀਅਨ ਰੋਅਜ਼ ਸਕੈਨ ਕੀਤੀਆਂ।

ਇਸਦਾ ਹੱਲ ਲੱਗਭਗ ਪੰਜ ਮਿੰਟਾਂ ਵਿੱਚ ਨਿਕਲ ਆਇਆ। ਅਸੀਂ CREATE INDEX CONCURRENTLY ਦੀ ਵਰਤੋਂ ਕਰਕੇ (user_id, status, created_at DESC) 'ਤੇ ਇੱਕ ਕੰਪੋਜ਼ਿਟ ਇੰਡੈਕਸ (composite index) ਬਣਾਇਆ ਤਾਂ ਜੋ ਟੇਬਲ ਆਨਲਾਈਨ ਰਹਿ ਸਕੇ।

ਨਤੀਜੇ:

  • ਕੁਐਰੀ ਦਾ ਸਮਾਂ 8,150 ਮਿਲੀਸੈਕਿੰਡ ਤੋਂ ਘਟ ਕੇ 0.14 ਮਿਲੀਸੈਕਿੰਡ ਰਹਿ ਗਿਆ।
  • API ਲੇਟੈਂਸੀ (latency) 8 ਸੈਕਿੰਡ ਤੋਂ ਘਟ ਕੇ 12 ਮਿਲੀਸੈਕਿੰਡ ਹੋ ਗਈ।
  • CPU ਦੀ ਵਰਤੋਂ 100% ਤੋਂ ਘਟ ਕੇ 8% ਤੋਂ ਵੀ ਘੱਟ ਹੋ ਗਈ।

ਸਿੱਖੇ ਗਏ ਸਬਕ:

  • ਲੋਕਲ ਟੈਸਟ ਗੁੰਮਰਾਹ ਕਰ ਸਕਦੇ ਹਨ; 100 ਰੋਅਜ਼ ਮਿਲੀਅਨ ਰੋਅਜ਼ ਦਾ ਬਦਲ ਨਹੀਂ ਹਨ।
  • ਫੋਰਨ ਕੀਜ਼ (foreign keys) ਨੂੰ ਇੰਡੈਕਸ ਕਰੋ—ਜ਼ਿਆਦਾਤਰ ORMs ਇਸ ਨੂੰ ਛੱਡ ਦਿੰਦੇ ਹਨ।
  • EXPLAIN ANALYZE ਚਲਾਓ; ਡਾਟਾਬੇਸ ਖੁਦ ਸਮੱਸਿਆ ਦੀ ਨਿਸ਼ਾਨਦੇਹੀ ਕਰਦਾ ਹੈ।
  • ਹੋਰ ਹਾਰਡਵੇਅਰ ਖਰੀਦਣ ਤੋਂ ਪਹਿਲਾਂ ਕੁਐਰੀਆਂ ਨੂੰ ਆਪਟੀਮਾਈਜ਼ (optimize) ਕਰੋ।

ਪਹਿਲਾਂ ਸਰਵਰਾਂ ਨੂੰ ਸਕੇਲ ਨਾ ਕਰੋ। ਕੁਐਰੀਆਂ ਨੂੰ ਸਕੇਲ ਕਰੋ।

Source: https://dev.to/mia_keller_ffd2584c046ecb/how-an-unindexed-column-silently-killed-our-database-under-load-and-the-5-minute-fix-m32