ഒരു ലളിതമായ ഡാറ്റാബേസ് തന്ത്രം ഇമെയിൽ പ്രൊസസിംഗ് 18 മടങ്ങ് വേഗത്തിലാക്കിയത് എങ്ങനെ

ഒരു ലളിതമായ ഡാറ്റാബേസ് തന്ത്രം ഇമെയിൽ പ്രൊസസിംഗ് 18 മടങ്ങ് വേഗത്തിലാക്കിയത് എങ്ങനെ

ഡാറ്റാബേസുമായുള്ള ആശയവിനിമയം കുറച്ചുകൊണ്ട് PostgreSQL CTE-കൾ 90 സെക്കൻഡ് ദൈർഘ്യമുള്ള ഒരു പ്രക്രിയയെ വെറും 5 സെക്കൻഡായി ചുരുക്കി

ഇമെയിൽ സിങ്ക് പ്രശ്നം

ഒരു ഫയലിൽ നിന്നുള്ള ഇമെയിൽ വിലാസങ്ങൾ ഒരു ഡാറ്റാബേസിലേക്ക് സിങ്ക് ചെയ്യുന്ന ഒരു ആപ്പ് നിങ്ങൾ നിർമ്മിക്കുകയാണെന്ന് സങ്കൽപ്പിക്കുക. നിങ്ങളുടെ ചുമതല: ഫയലിലെ എല്ലാ ഇമെയിലുകളും ആക്ടീവ് എന്ന് അടയാളപ്പെടുത്തുക, ഡാറ്റാബേസിലുണ്ടായിരുന്നതും എന്നാൽ ഫയലിൽ ഇനിയില്ലാത്തതുമായ ഏതൊരു ഇമെയിലും ഡിആക്ടീവ് ചെയ്യുക, ഓഡിറ്റിംഗിനായി ഓരോ മാറ്റത്തിന്റെയും റെക്കോർഡ് സൂക്ഷിക്കുക. ഇത് ലളിതമായി തോന്നാം—എന്നാൽ നിങ്ങൾ 1,00,000 വിലാസങ്ങൾ കൈകാര്യം ചെയ്യുമ്പോൾ, ലളിതമായ സമീപനം ഒരു തടസ്സമായി മാറുന്നു.

യാരോസ്ലാവ് പോഡോർവാനോവ് (Yaroslav Podorvanov) എന്ന ഡെവലപ്പർ അടുത്തിടെ, ഈ പ്രശ്നം പരിഹരിക്കാൻ 90 സെക്കൻഡ് എങ്ങനെ എടുത്തു എന്നും—അത് 5 സെക്കൻഡായി കുറച്ച PostgreSQL സാങ്കേതികവിദ്യ ഉപയോഗിച്ച് അദ്ദേഹം അത് തിരുത്തിയെഴുതിയെന്നും പങ്കുവെച്ചു. 8 July 2026-ൽ അവതരിപ്പിച്ച ഈ സമീപനം മനസ്സിലാക്കുന്നത് മൂല്യവത്താണ്, കാരണം ഡാറ്റാബേസുകൾ എങ്ങനെ പ്രവർത്തിക്കുന്നു എന്നതിനെക്കുറിച്ചുള്ള പ്രധാനപ്പെട്ട ഒരു കാര്യം ഇത് വെളിപ്പെടുത്തുന്നു: യഥാർത്ഥ ചെലവ് സാധാരണയായി വലിയ ജോലികളല്ല—നിങ്ങളുടെ കോഡും ഡാറ്റാബേസും തമ്മിലുള്ള സംഭാഷണമാണ്.

വേഗത കുറഞ്ഞ പതിപ്പ് എങ്ങനെയാണ് പ്രവർത്തിച്ചിരുന്നത്

യഥാർത്ഥ പരിഹാരം ജോലിയെ പ്രത്യേക ഘട്ടങ്ങളായി തിരിച്ചു:

  1. ഫയലിൽ നിന്നുള്ള പുതിയ ഇമെയിൽ വിലാസങ്ങൾ ഇൻസേർട്ട് ചെയ്യുക അല്ലെങ്കിൽ അപ്‌ഡേറ്റ് ചെയ്യുക
  2. ഫയലിൽ ഇല്ലാത്ത ഏതൊരു ഇമെയിൽ വിലാസവും ഡിആക്ടീവ് ചെയ്യുക
  3. ഓഡിറ്റിംഗിനായി ഒരു ഹിസ്റ്ററി ടേബിളിൽ ഓരോ മാറ്റവും റെക്കോർഡ് ചെയ്യുക

ഓരോ ഘട്ടവും അതിന്റേതായ ഡാറ്റാബേസ് ക്വറി ആയിരുന്നു. അതായത് കോഡിന് ഇത് ചെയ്യേണ്ടിവന്നു:

  • ഇമെയിൽ ലിസ്റ്റ് ഡാറ്റാബേസിലേക്ക് അയക്കുക
  • മറുപടിക്കായി കാത്തിരിക്കുക
  • മാറ്റം വരുത്തിയവയുടെ ID-കൾ നേടുക
  • ആ ID-കൾ വീണ്ടും ഡാറ്റാബേസിലേക്ക് അയക്കുക
  • വീണ്ടും കാത്തിരിക്കുക
  • ഡിആക്റ്റിവേഷനായി ഇത് ആവർത്തിക്കുക
  • ഹിസ്റ്ററി റെക്കോർഡുകൾക്കായി വീണ്ടും ആവർത്തിക്കുക

100,000 വിലാസങ്ങൾ ഉള്ളപ്പോൾ, ആ കാത്തിരിപ്പുകളെല്ലാം കൂടി ചേർന്ന് ആകെ 90 സെക്കൻഡായി.

CTE പരിഹാരം

ഒരു 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 സെക്കൻഡ് (slow version) → ~3 സെക്കൻഡ് (CTE)
  • 100,000 വിലാസങ്ങൾ: ~90 സെക്കൻഡ് (slow version) → ~5 സെക്കൻഡ് (CTE)
  • 1 ദശലക്ഷം വിലാസങ്ങൾ: ~30 സെക്കൻഡ് (CTE)

ഡാറ്റ എങ്ങനെ ഒഴുകുന്നു എന്ന് പുനഃസംഘടിപ്പിച്ചുകൊണ്ട് മാത്രമാണ് 100k കേസിൽ 18x വേഗത കൈവരിച്ചത്—ഡാറ്റാബേസിനെക്കൊണ്ട് കഠിനമായി ജോലി ചെയ്യിച്ചുകൊണ്ടല്ല, മറിച്ച് ബുദ്ധിപൂർവ്വം ജോലി ചെയ്യിച്ചുകൊണ്ടാണ്.

എന്തുകൊണ്ടാണ് ഇത് പ്രധാനം ആകുന്നത്

ഇവിടെയുള്ള പാഠം വൈരുദ്ധ്യാത്മകമായി തോന്നാം: ഡാറ്റാബേസുകളിൽ, റൗണ്ട്-ട്രിപ്പ് ചെലവ് (ഡാറ്റ അങ്ങോട്ടും ഇങ്ങോട്ടും അയക്കാൻ ചെലവഴിക്കുന്ന സമയം) പലപ്പോഴും യഥാർത്ഥ കമ്പ്യൂട്ടേഷനേക്കാൾ വളരെ കൂടുതലാണ്. അഞ്ച് യാത്രകളെ ഒന്നാക്കി സംയോജിപ്പിക്കുന്നതിലൂടെ, Podorvanov സമയം ലാഭിക്കുക മാത്രമല്ല ചെയ്തത്—അദ്ദേഹം സെർവർ ലോഡ് കുറയ്ക്കുകയും പ്രക്രിയ കൂടുതൽ അറ്റോമിക് ആക്കുകയും ചെയ്തു (ഒന്നെങ്കിൽ എല്ലാം വിജയിക്കുന്നു അല്ലെങ്കിൽ ഒന്നും സംഭവിക്കുന്നില്ല, ഇടയിലുള്ള അവസ്ഥകളൊന്നുമില്ലാതെ).

ഇതൊരു മാന്ത്രികവിദ്യയല്ല; എവിടെയും ബാധകമാകുന്ന ഒരു തത്വമാണിത്: അനാവശ്യമായ ആശയവിനിമയങ്ങൾ കുറയ്ക്കുക, സിസ്റ്റങ്ങൾ വേഗതയുള്ളതാകും. ഇമെയിൽ സിങ്കുകൾ, ബാച്ച് ഇമ്പോർട്ടുകൾ, അല്ലെങ്കിൽ ഒന്നിലധികം റീഡുകളും റൈറ്റുകളും ഒന്നിച്ചു ബന്ധിപ്പിക്കുന്ന ഏതൊരു പ്രക്രിയയ്ക്കും ഈ സാങ്കേതികവിദ്യ പ്രവർത്തിക്കുന്നു.

ഉപസംഹാരം

ഒരു ഡാറ്റാബേസ് പ്രക്രിയ മന്ദഗതിയിലാണെന്ന് തോന്നുമ്പോൾ, വില്ലൻ പലപ്പോഴും ക്വറി തന്നെയല്ല, മറിച്ച് നിങ്ങൾ എത്ര വ്യത്യസ്ത ക്വറികൾ പ്രവർത്തിപ്പിക്കുന്നു എന്നതാണ്. ഒന്നിലധികം പ്രക്രിയകളെ ഒരൊറ്റ അറ്റോമിക് ഘട്ടത്തിലേക്ക് സംയോജിപ്പിക്കാൻ CTE-കൾ നിങ്ങളെ അനുവദിക്കുന്നു, ഇത് റൗണ്ട്-ട്രിപ്പ് ഓവർഹെഡ് കുറയ്ക്കുകയും ത്രൂപുട്ട് ഗണ്യമായി മെച്ചപ്പെടുത്തുകയും ചെയ്യുന്നു. ഇമെയിൽ സിങ്കിംഗ് അല്ലെങ്കിൽ ബാച്ച് അപ്‌ലോഡുകൾ പോലുള്ള വർക്ക്‌ലോഡുകൾക്ക്, ഈ തരത്തിലുള്ള ഒപ്റ്റിമൈസേഷൻ 90 സെക്കൻഡ് പ്രക്രിയയും 5 സെക്കൻഡ് പ്രക്രിയയും തമ്മിലുള്ള വ്യത്യാസമായിരിക്കും.

നേട്ടങ്ങൾ

  • ഡാറ്റാബേസ് റൗണ്ട്-ട്രിപ്പുകൾ ഗണ്യമായി കുറയ്ക്കുന്നു, ലേറ്റൻസി കുറയ്ക്കുന്നു
  • ഡാറ്റാ സ്ഥിരത പുലർത്തുന്നു—എല്ലാ മാറ്റങ്ങളും ഒരൊറ്റ ട്രാൻസാക്ഷനിൽ അറ്റോമിക് ആയി സംഭവിക്കുന്നു
  • ആപ്ലിക്കേഷൻ കോഡ് ലളിതമാക്കുന്നു (കുറഞ്ഞ പ്രത്യേക ഫംഗ്ഷൻ കോളുകൾ)
  • ലീനിയറായി സ്കെയിൽ ചെയ്യുന്നു; അതേ ക്വറി തന്നെ 10k അല്ലെങ്കിൽ 1M വിലാസങ്ങൾക്കും പ്രവർത്തിക്കുന്നു
  • ഡാറ്റാബേസിന്റെ കഴിവുകളെ എതിർക്കുന്നതിന് പകരം അവയെ പ്രയോജനപ്പെടുത്തുന്നു

ദോഷങ്ങൾ

  • CTE സിന്റാക്സ് കൂടുതൽ സങ്കീർണ്ണമാണ്, ഡിബഗ് ചെയ്യാൻ കൂടുതൽ ബുദ്ധിമുട്ടായിരിക്കും
  • അഡ്വാൻസ്ഡ് SQL-ൽ പരിചയം ആവശ്യമാണ്—ഡാറ്റാബേസുകളിൽ പുതിയ ടീമുകൾക്ക് ഇത് അനുയോജ്യമല്ല
  • ഡാറ്റാബേസ് ലോഗുകൾ കൂടുതൽ സൂക്ഷ്മമല്ലാതായി തീരുന്നു (ഏത് ഘട്ടമാണ് മന്ദഗതിയിലായതെന്ന് കൃത്യമായി കാണാൻ ബുദ്ധിമുട്ടാണ്)
  • എല്ലാ ഡാറ്റാബേസുകളും CTE-കളെ ഒരേപോലെ പിന്തുണയ്ക്കുന്നില്ല
  • ഓവർഹെഡ് പ്രശ്നമല്ലാത്ത ചെറിയ ഡാറ്റാസെറ്റുകൾക്ക് ഇത് അനാവശ്യ ഭാരമായേക്കാം

ജാഗ്രത

ഈ ലേഖനം വിദ്യാഭ്യാസപരവും ഒരു യഥാർത്ഥ ലോക ഉദാഹരണത്തിൽ നിന്ന് എടുത്തതുമാണ്. സമാനമായ ഒപ്റ്റിമൈസേഷനുകൾ നടപ്പിലാക്കുമ്പോൾ, ഏതൊരു പ്ലേസ്‌ഹോൾഡർ മൂല്യങ്ങളും (@file_id അല്ലെങ്കിൽ @now പോലുള്ളവ) നിങ്ങളുടെ ആപ്ലിക്കേഷനിൽ നിന്നുള്ള യഥാർത്ഥ വേരിയബിളുകൾ ഉപയോഗിച്ച് മാറ്റുക, നിങ്ങളുടെ സ്വന്തം ഡാറ്റാ വോളിയം ഉപയോഗിച്ച് സമഗ്രമായി പരിശോധിക്കുക, കൂടാതെ പ്രൊഡക്ഷനിൽ ഉപയോഗിക്കുന്നതിന് മുമ്പ് യഥാർത്ഥ ഉറവിടവുമായി പൊരുത്തപ്പെടുന്നുണ്ടോ എന്ന് പരിശോധിച്ച് ഉറപ്പാക്കുക. ഡാറ്റാബേസ് പെർഫോമൻസ് സന്ദർഭത്തെ ആശ്രയിച്ചിരിക്കുന്നു; ഇവിടെ പ്രവർത്തിക്കുന്നത് നിങ്ങളുടെ പ്രത്യേക സ്കീമ, ഇൻഡെക്സുകൾ, ഹാർഡ്‌വെയർ എന്നിവയ്ക്കായി ട്യൂൺ ചെയ്യേണ്ടതായി വന്നേക്കാം.

അടിക്കടി ചോദിക്കുന്ന ചോദ്യങ്ങൾ

  • PostgreSQL-ൽ ഒരു CTE എന്നാൽ എന്താണ്, അത് എങ്ങനെയാണ് ക്വറി പെർഫോമൻസ് മെച്ചപ്പെടുത്തുന്നത്?
  • ഇമെയിൽ സിങ്ക് ചെയ്യൽ അല്ലാതെ മറ്റ് പ്രക്രിയകൾക്ക് CTE-കൾ ഉപയോഗിക്കാമോ?
  • എന്തെങ്കിലും തകരാറുണ്ടാകുമ്പോൾ ഒരു CTE ക്വറി നിങ്ങൾ എങ്ങനെ ഡിബഗ് ചെയ്യും?
  • ഒരു CTE-യും സ്റ്റോർഡ് പ്രൊസീജറും തമ്മിലുള്ള വ്യത്യാസം എന്താണ്?
  • എല്ലാ SQL ഡാറ്റാബേസുകളും ഒരേ രീതിയിലാണോ CTE-കളെ പിന്തുണയ്ക്കുന്നത്?
  • പ്രത്യേക ക്വറികൾ ഉണ്ടാക്കുന്നതിനേക്കാൾ CTE എപ്പോഴാണ് അനുയോജ്യമായ ടൂൾ ആകുന്നത്?
  • CTE-കൾ ഇൻഡെക്സ് ഉപയോഗത്തെയും ക്വറി പ്ലാനിംഗിനെയും എങ്ങനെ ബാധിക്കുന്നു?
  • ഒരു 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.