Forwarded from مدرسه مهندسی داده سپهرام
وقتی SQL هم حلقه For دارد! نگاهی به Lateral Join در PostgreSQL
اگر در حوزه نرمافزار، تحلیل داده یا دیتابیس کار میکنید، احتمالاً با انواع JOINهای معمول در SQL مثل INNER JOIN و LEFT JOIN آشنا هستید.
اما یکی از جوینهایی که کمتر دربارهاش صحبت میشود و در عین حال بسیار مفید و کاربردی محسوب میشود، LATERAL JOIN است.
بیایید با یک مثال شروع کنیم 👇
فرض کنید یک جدول از محصولات دارید و میخواهید برای هر محصول، آمارهایی مثل:
🔰 مجموع کل فروش،
🔰حجم فروش،
🔰تعداد مشتریان منحصربهفرد،
🔰و میانگین فروش
در سه ماه گذشته را بهدست آورید (به تفکیک ماه).
اگر بخواهید این کار را با زبانهایی مثل Python یا JavaScript انجام دهید، معمولاً یک حلقه (for) روی تمام محصولات اجرا میکنید و درون آن، برای هر محصول، محاسبات آماری مربوط به فروش را انجام میدهید.
در واقع، یک حلقه بیرونی برای محصولات و یک حلقه داخلی برای فروشهای هر محصول دارید. در SQL هم میتوان دقیقاً همین رفتار را شبیهسازی کرد: با استفاده از LATERAL JOIN.
اینجاست که Lateral مثل یک پل ارتباطی عمل میکند:
به همین دلیل معمولاً از CROSS JOIN LATERAL استفاده میکنیم، چون شرط اتصال درون زیرکوئری و با WHERE تعریف میشود و در اینجا Inner Join معنا نخواهد داشت.
💫 نتیجه این رهیافت
میتوانید بهسادگی کوئریهایی بنویسید که مثلاً:
🌟 «ده محصول پرفروش هر کتگوری» را پیدا کند،
🌟یا برای هر مشتری، آخرین تراکنش ثبتشدهاش را نمایش دهد،
🌟یا حتی تحلیلهای زمانی و Top-N را مستقیماً داخل SQL انجام دهد: بدون نیاز به کدهای پیچیده و توابع پنجرهای
🎥 برای آشنایی دقیقتر با این مفهوم، یک ویدئوی آموزشی حدود ۴۰ دقیقهای آماده کردهام که در آن، با مثالهای واقعی و کاربردی نحوهی استفاده از LATERAL JOIN را گامبهگام توضیح دادهام.
🔗 لینک مشاهده ویدئو در یوتیوب:
👉 https://youtu.be/vVc2EewTSQU
💡 در این ویدئو یاد موارد زیر را به صورت عملی مرور میکنیم:
✅ایدهی اصلی و کاربرد LATERAL JOIN
✅تفاوت آن با جوینهای معمول
✅نوشتن کوئریهای Top-N per Group
✅تحلیل دادههای واقعی (مشتریان، فروش، زمان)
✅و نکات مهم برای بهینهسازی عملکرد کوئری
📚 این ویدئو بخشی از دورهی PostgreSQL Practical Course در مدرسه مهندسی داده سپهرام است.
👉 https://sepahram.ir/courses
#PostgreSQL #SQL #DataEngineering #Database #LateralJoin #Sepahram #BigData #PostgresTutorial #Analytics
اگر در حوزه نرمافزار، تحلیل داده یا دیتابیس کار میکنید، احتمالاً با انواع JOINهای معمول در SQL مثل INNER JOIN و LEFT JOIN آشنا هستید.
اما یکی از جوینهایی که کمتر دربارهاش صحبت میشود و در عین حال بسیار مفید و کاربردی محسوب میشود، LATERAL JOIN است.
بیایید با یک مثال شروع کنیم 👇
فرض کنید یک جدول از محصولات دارید و میخواهید برای هر محصول، آمارهایی مثل:
🔰 مجموع کل فروش،
🔰حجم فروش،
🔰تعداد مشتریان منحصربهفرد،
🔰و میانگین فروش
در سه ماه گذشته را بهدست آورید (به تفکیک ماه).
اگر بخواهید این کار را با زبانهایی مثل Python یا JavaScript انجام دهید، معمولاً یک حلقه (for) روی تمام محصولات اجرا میکنید و درون آن، برای هر محصول، محاسبات آماری مربوط به فروش را انجام میدهید.
در واقع، یک حلقه بیرونی برای محصولات و یک حلقه داخلی برای فروشهای هر محصول دارید. در SQL هم میتوان دقیقاً همین رفتار را شبیهسازی کرد: با استفاده از LATERAL JOIN.
اینجاست که Lateral مثل یک پل ارتباطی عمل میکند:
⚡️ به زیرکوئری اجازه میدهد به دادههای هر ردیف از جدول اصلی دسترسی داشته باشد. یعنی در زیرکوئری، رکوردها ابتدا بر اساس رابطه آنها با جدول اصلی فیلتر میشوند و سپس محاسبات آماری روی آنها انجام میشود و نهایتا هم در کنار رکوردهای جدول اصلی قرار میگیرند.
به همین دلیل معمولاً از CROSS JOIN LATERAL استفاده میکنیم، چون شرط اتصال درون زیرکوئری و با WHERE تعریف میشود و در اینجا Inner Join معنا نخواهد داشت.
💫 نتیجه این رهیافت
میتوانید بهسادگی کوئریهایی بنویسید که مثلاً:
🌟 «ده محصول پرفروش هر کتگوری» را پیدا کند،
🌟یا برای هر مشتری، آخرین تراکنش ثبتشدهاش را نمایش دهد،
🌟یا حتی تحلیلهای زمانی و Top-N را مستقیماً داخل SQL انجام دهد: بدون نیاز به کدهای پیچیده و توابع پنجرهای
🎥 برای آشنایی دقیقتر با این مفهوم، یک ویدئوی آموزشی حدود ۴۰ دقیقهای آماده کردهام که در آن، با مثالهای واقعی و کاربردی نحوهی استفاده از LATERAL JOIN را گامبهگام توضیح دادهام.
🔗 لینک مشاهده ویدئو در یوتیوب:
👉 https://youtu.be/vVc2EewTSQU
💡 در این ویدئو یاد موارد زیر را به صورت عملی مرور میکنیم:
✅ایدهی اصلی و کاربرد LATERAL JOIN
✅تفاوت آن با جوینهای معمول
✅نوشتن کوئریهای Top-N per Group
✅تحلیل دادههای واقعی (مشتریان، فروش، زمان)
✅و نکات مهم برای بهینهسازی عملکرد کوئری
📚 این ویدئو بخشی از دورهی PostgreSQL Practical Course در مدرسه مهندسی داده سپهرام است.
👉 https://sepahram.ir/courses
#PostgreSQL #SQL #DataEngineering #Database #LateralJoin #Sepahram #BigData #PostgresTutorial #Analytics
❤8👍3
معماریهای مدرن؛ زمان بازنگری در نقش لایه کش فرا رسیده است؟
برای سالها، Redis سلطان بیرقیب کش کردن داده در حافظه است.
تقریباً هر معماری استانداردی یک «لایه کش» دارد:
✨ درخواست میآید → اول سراغ Redis → اگر نبود → میرود سراغ دیتابیس → و نتیجه دوباره در Redis ذخیره میشود.
این الگو آنقدر جا افتاده است که کمتر کسی جرئت میکند بپرسد:
«آیا واقعاً همیشه به Redis نیاز داریم؟»
اما با پیشرفتهای اخیر دیتابیسها - مخصوصاً #PostgreSQL - حالا این سؤال دوباره ارزش پرسیدن دارد.
و داستان تیمی که اخیراً توانست کل لایه Redis خود را حذف کند، یک نمونه جذاب برای ما مهندسین داده است.
👉 https://freedium-mirror.cfd/https://medium.com/@ArkProtocol1/why-postgres-18-let-me-delete-a-whole-cache-tier-bba2b4f1c742
🔹 بیایید داستان را با هم مرور کنیم…
یک تیم محصول، مثل بسیاری از ما، سالها بود که برای پاسخهای سریع از Redis استفاده میکرد. اما در روزهای پر ترافیک، خود Redis یک پای داستان بود:
⚠️بار CPU بالا
⚠️ تاخیرهای عجیب
⚠️شبکه تحت فشار
درحالیکه دیتابیس… نسبتاً آرام و بیکار نشسته!
نقطه عطف زمانی بود که آنها PostgreSQL 18 را تست کردند، نسخهای با تغییرات جدی:
⚡️امکان I/O ناهمگام واقعی
⚡️بهبودهای چشمگیر در استفاده از ایندکسها
⚡️امکان virtual generated columns برای محاسبات سریعتر و بدون لایه جانبی
اینها فقط «بهبود» نبود؛ بازی را عوض کرد.
تیم تصمیم گرفت یک آزمایش مخفیانه انجام دهد:
یک endpoint بسیار شلوغ را مستقیم روی #PostgreSQL بگذارد، بدون #Redis.
انتظار داشتند کندتر شود.
اما نتیجه دقیقاً برعکس بود:
🔰 معیار p95 از ۷۲ میلیثانیه → رسید به ۵۴ میلیثانیه
🔰 نرخ hit rate از ۹۱٪ → شد ۱۰۰٪
🔰 و دیگر خبری از فشار شبکه و CPU نبود.
در واقع لایه کش نهتنها کمکی نکرده بود، بلکه گلوگاه اصلی سیستم شده بود.
در نهایت، آنها با خیال راحت Redis را کنار گذاشتند.
معماری سادهتر شد، پایش آسانتر شد، و منبع داده از دوگانگی خارج شد.
از آن مهمتر: عملکرد بهتر شد.
رد پای یک روند بزرگتر: تجربه #ScyllaDB
سال گذشته هم در وبلاگ ScyllaDB نمونه مشابهی دیدم: جایی که تیم SecurityScorecard به این نتیجه رسیده بود که با توجه به سرعت بالا، معماری توزیعشده و کش داخلی ScyllaDB، دیگر نیازی به یک لایه Redis جداگانه ندارند. آنها نیز مانند مثال بالا دریافتند که پیچیدگی همگامسازی دیتابیس و کش، در برابر توان پردازشی دیتابیسهای مدرن، برای برخی سناریوها توجیه خود را از دست داده است.
https://www.scylladb.com/compare/scylladb-vs-cache
🔹 درس ماجرا چیست؟
این داستان نمیگوید «Redis را حذف کنید».
ردیس همچنان یک ابزار قدرتمند و ضروری برای بسیاری از سناریوهاست.
اما یک نکته مهم را روشن میکند:
گاهی فناوریهای پایه آنقدر جلو میروند که معماریهای کهنه دیگر بهترین انتخاب نیستند.
💡شاید وقت آن باشد که به جای تکرار الگوهای سالهای گذشته، دوباره از خود بپرسیم:
⚡️ آیا دیتابیس ما امروز آنقدر قدرتمند شده که خودش نقش کش را بازی کند؟
⚡️ آیا لایه کش واقعاً سرعتدهنده است یا ناخواسته گره اضافه کردهایم؟
⚡️ آیا پیچیدگی اضافه همیشه ارزشش را دارد؟
برای سالها، Redis سلطان بیرقیب کش کردن داده در حافظه است.
تقریباً هر معماری استانداردی یک «لایه کش» دارد:
✨ درخواست میآید → اول سراغ Redis → اگر نبود → میرود سراغ دیتابیس → و نتیجه دوباره در Redis ذخیره میشود.
این الگو آنقدر جا افتاده است که کمتر کسی جرئت میکند بپرسد:
«آیا واقعاً همیشه به Redis نیاز داریم؟»
اما با پیشرفتهای اخیر دیتابیسها - مخصوصاً #PostgreSQL - حالا این سؤال دوباره ارزش پرسیدن دارد.
و داستان تیمی که اخیراً توانست کل لایه Redis خود را حذف کند، یک نمونه جذاب برای ما مهندسین داده است.
👉 https://freedium-mirror.cfd/https://medium.com/@ArkProtocol1/why-postgres-18-let-me-delete-a-whole-cache-tier-bba2b4f1c742
🔹 بیایید داستان را با هم مرور کنیم…
یک تیم محصول، مثل بسیاری از ما، سالها بود که برای پاسخهای سریع از Redis استفاده میکرد. اما در روزهای پر ترافیک، خود Redis یک پای داستان بود:
⚠️بار CPU بالا
⚠️ تاخیرهای عجیب
⚠️شبکه تحت فشار
درحالیکه دیتابیس… نسبتاً آرام و بیکار نشسته!
نقطه عطف زمانی بود که آنها PostgreSQL 18 را تست کردند، نسخهای با تغییرات جدی:
⚡️امکان I/O ناهمگام واقعی
⚡️بهبودهای چشمگیر در استفاده از ایندکسها
⚡️امکان virtual generated columns برای محاسبات سریعتر و بدون لایه جانبی
اینها فقط «بهبود» نبود؛ بازی را عوض کرد.
تیم تصمیم گرفت یک آزمایش مخفیانه انجام دهد:
یک endpoint بسیار شلوغ را مستقیم روی #PostgreSQL بگذارد، بدون #Redis.
انتظار داشتند کندتر شود.
اما نتیجه دقیقاً برعکس بود:
🔰 معیار p95 از ۷۲ میلیثانیه → رسید به ۵۴ میلیثانیه
🔰 نرخ hit rate از ۹۱٪ → شد ۱۰۰٪
🔰 و دیگر خبری از فشار شبکه و CPU نبود.
در واقع لایه کش نهتنها کمکی نکرده بود، بلکه گلوگاه اصلی سیستم شده بود.
در نهایت، آنها با خیال راحت Redis را کنار گذاشتند.
معماری سادهتر شد، پایش آسانتر شد، و منبع داده از دوگانگی خارج شد.
از آن مهمتر: عملکرد بهتر شد.
رد پای یک روند بزرگتر: تجربه #ScyllaDB
سال گذشته هم در وبلاگ ScyllaDB نمونه مشابهی دیدم: جایی که تیم SecurityScorecard به این نتیجه رسیده بود که با توجه به سرعت بالا، معماری توزیعشده و کش داخلی ScyllaDB، دیگر نیازی به یک لایه Redis جداگانه ندارند. آنها نیز مانند مثال بالا دریافتند که پیچیدگی همگامسازی دیتابیس و کش، در برابر توان پردازشی دیتابیسهای مدرن، برای برخی سناریوها توجیه خود را از دست داده است.
https://www.scylladb.com/compare/scylladb-vs-cache
✅ بنابراین اگر در پروژههای خود بهصورت پیشفرض همهچیز را به Redis میسپارید، شاید وقت آن رسیده باشد که امکانات دیتابیسهای جدید، یا حتی توان واقعی دیتابیس اصلیتان، را دوباره بررسی کنید. گاهی پاسخ سریعتر و سادهتر، همانجایی است که سالها از آن عبور کردهایم.
🔹 درس ماجرا چیست؟
این داستان نمیگوید «Redis را حذف کنید».
ردیس همچنان یک ابزار قدرتمند و ضروری برای بسیاری از سناریوهاست.
اما یک نکته مهم را روشن میکند:
گاهی فناوریهای پایه آنقدر جلو میروند که معماریهای کهنه دیگر بهترین انتخاب نیستند.
💡شاید وقت آن باشد که به جای تکرار الگوهای سالهای گذشته، دوباره از خود بپرسیم:
⚡️ آیا دیتابیس ما امروز آنقدر قدرتمند شده که خودش نقش کش را بازی کند؟
⚡️ آیا لایه کش واقعاً سرعتدهنده است یا ناخواسته گره اضافه کردهایم؟
⚡️ آیا پیچیدگی اضافه همیشه ارزشش را دارد؟
❤1👍1