कैसे एक साधारण डेटाबेस ट्रिक ने ईमेल प्रोसेसिंग 18x तेज़ कर दी

कैसे एक साधारण डेटाबेस ट्रिक ने ईमेल प्रोसेसिंग 18x तेज़ कर दी

PostgreSQL CTEs ने डेटाबेस से बातचीत कम करके 90-सेकंड के ऑपरेशन को घटाकर केवल 5 सेकंड कर दिया

ईमेल सिंक की समस्या

मान लीजिए कि आप एक ऐसा ऐप बना रहे हैं जो किसी फ़ाइल से डेटाबेस में ईमेल पते सिंक करता है। आपका कार्य: फ़ाइल के सभी ईमेल को सक्रिय के रूप में चिह्नित करना, डेटाबेस में मौजूद लेकिन अब फ़ाइल में न होने वाले ईमेल को निष्क्रिय करना, और ऑडिटिंग के लिए प्रत्येक परिवर्तन का रिकॉर्ड रखना। यह सीधा लगता है—लेकिन जब आप 100,000 पतों के साथ काम कर रहे होते हैं, तो सीधा तरीका एक बाधा (bottleneck) बन जाता है।

Yaroslav Podorvanov नाम के एक डेवलपर ने हाल ही में साझा किया कि कैसे इस सटीक समस्या को हल करने में 90 सेकंड लगे—जब तक कि उन्होंने इसे एक PostgreSQL तकनीक का उपयोग करके फिर से नहीं लिखा जिसने इसे घटाकर केवल 5 सेकंड कर दिया। On 8 July 2026, यह दृष्टिकोण समझने योग्य है क्योंकि यह डेटाबेस काम करने के तरीके के बारे में कुछ महत्वपूर्ण उजागर करता है: वास्तविक लागत आमतौर पर भारी काम (heavy lifting) की नहीं होती—यह आपके कोड और डेटाबेस के बीच की बातचीत की होती है।

धीमा संस्करण कैसे काम करता था

मूल समाधान ने काम को अलग-अलग चरणों में विभाजित किया था:

  1. फ़ाइल से नए ईमेल पते सम्मिलित (insert) या अद्यतन (update) करें
  2. उन सभी ईमेल पतों को निष्क्रिय (deactivate) करें जो फ़ाइल में नहीं थे
  3. ऑडिटिंग के लिए इतिहास तालिका (history table) में प्रत्येक परिवर्तन को रिकॉर्ड करें

प्रत्येक चरण अपनी स्वयं की डेटाबेस क्वैरी था। इसका मतलब था कि कोड को:

  • ईमेल सूची को डेटाबेस पर भेजना पड़ता था
  • प्रतिक्रिया का इंतज़ार करना पड़ता था
  • जो बदला उसकी IDs प्राप्त करनी पड़ती थीं
  • उन IDs को वापस डेटाबेस पर भेजना पड़ता था
  • दोबारा इंतज़ार करना पड़ता था
  • निष्क्रियकरण (deactivation) के लिए दोहराना पड़ता था
  • इतिहास रिकॉर्ड के लिए फिर से दोहराना पड़ता था

100,000 पतों के साथ, वह सारा इंतज़ार जुड़ गया: कुल 90 सेकंड।

CTE समाधान

A Common Table Expression (CTE) PostgreSQL का एक तरीका है जो आपको एक जटिल क्वैरी को नाम दिए गए, पुन: प्रयोज्य टुकड़ों में तोड़ने की अनुमति देता है—यह सब एक ही डेटाबेस ऑपरेशन के भीतर होता है। डेटाबेस में पांच अलग-अलग चक्कर लगाने के बजाय, Podorvanov ने सब कुछ एक क्वैरी में स्थानांतरित कर दिया:

WITH
  data (email) AS (
    SELECT UNNEST(@emails::VARCHAR[])
  ),
  deactivated (id) AS (
    UPDATE rtt_emails
    SET active = FALSE, updated_at = @now::TIMESTAMP
    WHERE email NOT IN (SELECT email FROM data)
    AND active = TRUE
    RETURNING id
  ),
  activated (id) AS (
    INSERT INTO rtt_emails (email, active, created_at, updated_at)
    SELECT email, TRUE, @now::TIMESTAMP, @now::TIMESTAMP
    FROM data
    ON CONFLICT (email) DO UPDATE
    SET active = EXCLUDED.active, updated_at = EXCLUDED.updated_at
    WHERE rtt_emails.active IS DISTINCT FROM EXCLUDED.active
    RETURNING id
  ),
  deactivated_history AS (
    INSERT INTO rtt_email_history (email_id, active, file_id, created_at)
    SELECT id, FALSE, @file_id::BIGINT, @now::TIMESTAMP
    FROM deactivated
  ),
  activated_history AS (
    INSERT INTO rtt_email_history (email_id, active, file_id, created_at)
    SELECT id, TRUE, @file_id::BIGINT, @now::TIMESTAMP
    FROM activated
  )
SELECT
  (SELECT COUNT(*) FROM activated) AS activated_count,
  (SELECT COUNT(*) FROM deactivated) AS deactivated_count;

जो जटिल दिखता है वह वास्तव में वही कर रहा है जो अलग-अलग क्वैरीज़ करती थीं—लेकिन डेटाबेस के साथ एक ही बातचीत में। CTE टुकड़ों को एक साथ जोड़ता है: आने वाला डेटा एक्टिवेशन चरण में जाता है, जो हिस्ट्री चरण में जाता है, और इसी तरह।

गति में वृद्धि

परिणाम खुद बोलते हैं:

  • 10,000 पते: ~5 सेकंड (धीमा संस्करण) → ~3 सेकंड (CTE)
  • 100,000 पते: ~90 सेकंड (धीमा संस्करण) → ~5 सेकंड (CTE)
  • 1 मिलियन पते: ~30 सेकंड (CTE)

यह 100k मामले के लिए 18x की गति वृद्धि है, जो विशुद्ध रूप से डेटा प्रवाह के पुनर्गठन द्वारा हासिल की गई है—डेटाबेस को अधिक मेहनत कराने से नहीं, बल्कि इसे अधिक समझदारी से काम कराने से।

यह क्यों महत्वपूर्ण है

यहाँ सबक सहज ज्ञान के विपरीत है: डेटाबेस में, राउंड-ट्रिप लागत (डेटा को आगे-पीछे भेजने में बिताया गया समय) अक्सर वास्तविक गणना से बहुत अधिक होती है। पांच चक्करों को एक में समेकित करके, Podorvanov ने केवल समय नहीं बचाया—उन्होंने सर्वर लोड को भी कम किया और ऑपरेशन को अधिक परमाणु (atomic) बना दिया (या तो सब कुछ सफल होता है या कुछ भी नहीं, बीच में कोई आंशिक स्थिति नहीं होती)।

यह कोई जादू नहीं है; यह एक ऐसा सिद्धांत है जो कहीं भी लागू होता है: अनावश्यक आगे-पीछे को कम करें, और सिस्टम तेज़ हो जाते हैं। यह तकनीक ईमेल सिंक, बैच इंपोर्ट, या किसी भी ऐसे ऑपरेशन के लिए काम करती है जो कई रीड्स और राइट्स को एक साथ जोड़ती है।

निष्कर्ष

जब कोई डेटाबेस ऑपरेशन धीमा लगता है, तो अपराधी अक्सर स्वयं क्वैरी नहीं होती बल्कि यह होता है कि आप कितनी अलग-अलग क्वैरीज़ चला रहे हैं। CTEs आपको कई ऑपरेशन्स को एक परमाणु चरण में संयोजित करने की अनुमति देते हैं, जिससे राउंड-ट्रिप ओवरहेड में भारी कमी आती है और थ्रूपुट में नाटकीय रूप से सुधार होता है। ईमेल सिंकिंग या बैच अपलोड जैसे वर्कलोड के लिए, इस प्रकार का अनुकूलन 90-सेकंड के ऑपरेशन और 5-सेकंड के ऑपरेशन के बीच का अंतर हो सकता है।

गुण

  • डेटाबेस राउंड-ट्रिप्स को नाटकीय रूप से कम करता है, जिससे लेटेंसी घटती है
  • डेटा संगति बनाए रखता है—सभी परिवर्तन एक ही ट्रांजेक्शन में परमाणु रूप से (atomically) होते हैं
  • एप्लिकेशन कोड को सरल बनाता है (कम अलग फ़ंक्शन कॉल)
  • रैखिक रूप से स्केल करता है; वही क्वैरी 10k या 1M पतों के लिए काम करती है
  • डेटाबेस की ताकतों का लाभ उठाता है न कि उनसे मुकाबला करता है

दोष

  • CTE सिंटैक्स अधिक जटिल है और इसे डिबग करना अधिक कठिन हो सकता है
  • उन्नत SQL से परिचित होने की आवश्यकता होती है—डेटाबेस में नई टीमों के लिए आदर्श नहीं है
  • डेटाबेस लॉग कम बारीक (granular) हो जाते हैं (यह देखना कठिन होता है कि कौन सा चरण धीमा था)
  • सभी डेटाबेस CTEs का समान रूप से अच्छी तरह से समर्थन नहीं करते हैं
  • छोटे डेटासेट के लिए यह अत्यधिक (overkill) हो सकता है जहाँ ओवरहेड से कोई फर्क नहीं पड़ता

सावधानी

यह लेख शैक्षणिक है और वास्तविक दुनिया के उदाहरण से लिया गया है। समान अनुकूलन लागू करते समय, किसी भी प्लेसहोल्डर मान (जैसे @file_id या @now) को अपने एप्लिकेशन के वास्तविक वेरिएबल से बदलें, अपने स्वयं के डेटा वॉल्यूम के साथ अच्छी तरह से परीक्षण करें, और प्रोडक्शन में उन पर भरोसा करने से पहले मूल स्रोत के खिलाफ दावों को सत्यापित करें। डेटाबेस का प्रदर्शन अत्यधिक संदर्भ-निर्भर है; यहाँ जो काम करता है उसे आपकी विशिष्ट स्कीमा, इंडेक्स और हार्डवेयर के लिए ट्यूनिंग की आवश्यकता हो सकती है।

अक्सर पूछे जाने वाले प्रश्न

  • PostgreSQL में CTE क्या है और यह क्वैरी के प्रदर्शन में कैसे सुधार करता है?
  • क्या CTEs का उपयोग ईमेल सिंकिंग के अलावा अन्य ऑपरेशन्स के लिए किया जा सकता है?
  • जब कुछ गलत हो जाता है तो आप CTE क्वैरी को कैसे डिबग करते हैं?
  • CTE और stored procedure के बीच क्या अंतर है?
  • क्या सभी SQL डेटाबेस CTEs का समर्थन एक ही तरह से करते हैं?
  • अलग-अलग क्वैरीज़ बनाने के बजाय CTE कब सही टूल होता है?
  • CTEs इंडेक्स उपयोग और क्वैरी प्लानिंग को कैसे प्रभावित करते हैं?
  • यदि कोई CTE ऑपरेशन बीच में ही विफल हो जाता है तो क्या होता है?

टैग

#postgres #database #performance #cte #sql #optimization #batch-processing #postgresql

Free field guide

Kubernetes Security Checklist

Harden cluster access, workload identity, pod security, network boundaries, software supply chain, secrets, and operational monitoring.