مستوى المقال: محترف (Advanced) — يفترض إنك تعرف PostgreSQL، EXPLAIN ANALYZE، و GROUP BY aggregations. لو لسه بتبدأ مع indexes، ابدأ بمقال B-Tree للمبتدئ الأول.
Materialized Views في PostgreSQL: السلاح الخفي لتحويل تقاريرك من 8 ثوانٍ لـ 40 مللي ثانية
لو dashboard المبيعات الأسبوعي عند المدير بياخد 8 ثوانٍ يفتح، PostgreSQL مش بطيء. المشكلة إن الـ query بيعمل JOIN ثلاثي على 240 مليون سطر و GROUP BY على date_trunc و SUM في كل مرة المدير يضغط refresh. Materialized View بـ 14 سطر SQL بيخزّن النتيجة كجدول فيزيكال على القرص، والـ query التالية بترجع في 38 مللي ثانية بدون لمس سطر كود واحد في تطبيقك.
المشكلة باختصار: ليه الـ aggregation بياكل وقتك
السيناريو الحقيقي: شركة e-commerce عربية، جدول orders فيه 62 مليون صف، جدول order_items فيه 240 مليون صف. الـ dashboard بيعرض المبيعات حسب المنتج لآخر 12 أسبوع. الـ query:
SELECT
date_trunc('week', o.created_at) AS week_start,
oi.product_id,
SUM(oi.quantity * oi.unit_price) AS revenue
FROM orders o
JOIN order_items oi ON oi.order_id = o.id
WHERE o.status = 'completed'
AND o.created_at >= NOW() - INTERVAL '12 weeks'
GROUP BY 1, 2;الـ EXPLAIN ANALYZE بيقولك: HashAggregate على 38 مليون صف، الزمن 7,842 مللي ثانية، الذاكرة 4.2GB. الـ DBA حاول partition table، حاول read replica، حاول يزوّد RAM. كل ده مش هيحل المشكلة، لأن الـ aggregation محتاج يلمس كل صف من الـ 38 مليون. الـ index مش هينفع هنا لأن الـ query بيرجع 12 أسبوع كاملين.
المفهوم بمثال محل البقالة (للي مش عارف Materialized View)
تخيل محل بقالة عنده دفتر فواتير فيه 50,000 فاتورة من السنة كلها. كل ما المالك يدخل المحل ويسأل: "إيه أكتر منتج باع الأسبوع اللي فات؟"، الموظف بيفتح الدفتر ويبدأ يقرأ فاتورة فاتورة، يجمع ويصنّف. العملية دي بتاخد 30 دقيقة.
الموظف الذكي قرر إنه نهاية كل أسبوع يقعد ساعة واحدة، يحسب كل المنتجات ويكتب النتايج في كشف منفصل اسمه "ملخص الأسبوع". لما المالك يسأل ثاني مرة، الموظف يرد في 3 ثوانٍ من الكشف ده.
الكشف ده هو Materialized View. الفرق بينه وبين View العادي إن View العادي مجرد "وصفة" بتتنفّذ في كل مرة، بينما Materialized View نتيجة محفوظة فعلاً على القرص ومتاحة للقراءة المباشرة.
التعريف العلمي الدقيق
حسب توثيق PostgreSQL 16 الرسمي، الـ Materialized View هو "جدول مخزّن فيزيكاليًا يحتوي على نتيجة استعلام، يمكن تحديثه عند الطلب أو بشكل دوري". الفروق الجوهرية:
- View عادي: alias لـ query، بيتنفّذ من الصفر كل استدعاء. صفر تخزين، صفر تحديث، لكن صفر تسريع.