Get a quote

استراتيجيات الـ Index في PostgreSQL التي تُحدث فرقاً حقيقياً في أنظمة SaaS

أغلب مشاكل الأداء في قواعد بيانات PostgreSQL لا تأتي من غياب الـ Index، بل من استخدام النوع الخاطئ أو البنية الخاطئة. دليل عملي من تجربة إنتاج حقيقية.

أغلب مشاكل الأداء في قواعد بيانات PostgreSQL لا تأتي من غياب الـ Index، بل من استخدام النوع الخاطئ أو ترتيب الأعمدة الخاطئ أو تراكم فهارس لا يستخدمها أحد. في هذا المقال نشرح كيف نتعامل مع هذه المشكلة في أنظمة SaaS حقيقية نُشغّلها على AWS في لبنان وعموم منطقة الشرق الأوسط.

لماذا لا يحل إضافة Index المشكلة دائماً

حين يبطؤ الاستعلام، تكون الغريزة الأولى هي إضافة Index على العمود المُصفَّى. أحياناً يعمل هذا، وكثيراً لا يعمل. المشكلة أن PostgreSQL يستخدم خوارزمية تقدير التكلفة لاتخاذ قرار استخدام الـ Index من عدمه. إذا كان جدول staging يحتوي 800 صف بينما جدول الإنتاج يحتوي 2.4 مليون صف، فقد يتجاهل المُحسِّن الفهرسَ في بيئة التطوير ويستخدمه في الإنتاج، أو يُخطئ في كلا البيئتين بسبب إحصاءات غير دقيقة.

قبل أي تعديل على الفهارس، الخطوة الصحيحة هي قراءة خطة تنفيذ الاستعلام الفعلية:

EXPLAIN (ANALYZE, BUFFERS)
SELECT id, status, created_at
FROM orders
WHERE tenant_id = $1
  AND status = 'pending'
ORDER BY created_at DESC
LIMIT 50;

خيار BUFFERS يوضح عدد الصفحات التي قُرئت من القرص مقابل ما خُدِم من ذاكرة التخزين المؤقت. إذا رأيت shared read=18000 لاستعلام يُعيد 50 صفاً، فهناك مشكلة حقيقية.

ترتيب الأعمدة في الفهرس المركّب

في أنظمة SaaS متعددة المستأجرين، ينبغي دائماً وضع tenant_id أولاً في الفهرس المركّب، حتى لو كانت قيمه قليلة التنوع على مستوى الجدول كله. السبب بسيط: كل استعلام تقريباً يُصفِّي بـ tenant_id أولاً، مما يُضيّق نطاق البحث إلى بيانات مستأجر واحد قبل تطبيق أي فلتر آخر.

-- الصواب في أنظمة متعددة المستأجرين
CREATE INDEX idx_orders_tenant_status_time
  ON orders(tenant_id, status, created_at DESC);

الفهارس الجزئية: الأداة الأكثر إهمالاً في SaaS

الفهرس الجزئي يُغطي فقط الصفوف التي تستوفي شرطاً محدداً. في تطبيقات SaaS، معظم استعلامات العمليات اليومية تمس جزءاً صغيراً من البيانات: الوظائف المعلّقة، الطلبات غير المعالجة، الاشتراكات النشطة.

CREATE INDEX idx_jobs_pending
  ON background_jobs(tenant_id, scheduled_at)
  WHERE status = 'pending';

في نظام فواتير نُشغّله لعميل SaaS يحتوي 40,000 اشتراك، نسبة النشطة منها لا تتجاوز 12%. الفهرس الجزئي على الاشتراكات النشطة أصغر بعشر مرات من الفهرس الكامل، ويتسع للتخزين المؤقت في الذاكرة بالكامل، مما يُلغي قراءات القرص بشكل شبه تام.

فهارس التغطية وعمليات المسح دون الرجوع إلى الجدول

كل مرة يحتاج فيها الاستعلام إلى عمود غير موجود في الفهرس، يقوم PostgreSQL بما يُسمى heap fetch: يتبع مؤشراً من الفهرس إلى صفحة الجدول الأصلية. عند الحمل الثقيل، هذا مكلف.

CREATE INDEX idx_orders_tenant_list
  ON orders(tenant_id, status, created_at DESC)
  INCLUDE (id, total_amount, customer_id);

باستخدام INCLUDE، يمكن لـ PostgreSQL تنفيذ Index Only Scan دون لمس الجدول الأصلي. في خطة التنفيذ، ابحث عن Index Only Scan بدلاً من Index Scan. الفرق في الأداء على الجداول الساخنة قد يبلغ 60-80%.

العثور على الفهارس غير المستخدمة وحذفها

كل فهرس له تكلفة كتابة. العمليات INSERT وUPDATE وDELETE تُحدِّث كل فهارس الجدول. في أنظمة الكتابة الثقيلة، جدول بثمانية فهارس أبطأ بكثير من جدول بثلاثة فهارس مُختارة بعناية.

SELECT tablename, indexname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
  AND schemaname = 'public'
ORDER BY tablename;

أي فهرس بصفر عمليات مسح بعد أسابيع من حركة الإنتاج الحقيقية يمكن حذفه بأمان. قبل الحذف، تحقق أنه لم يُنشأ مؤخراً وأنه ليس مخصصاً لمهمة شهرية تُشغَّل مرة في الشهر.

دروس من الإنتاج

استراتيجية الفهارس في قواعد بيانات PostgreSQL لأنظمة SaaS تعتمد على قواعد موثوقة:

  • ضع tenant_id أولاً دائماً في الفهارس المركّبة لأنظمة متعددة المستأجرين.
  • استخدم الفهارس الجزئية على المجموعات التشغيلية: الوظائف المعلّقة، الاشتراكات النشطة، الأحداث غير المعالجة.
  • استخدم INCLUDE لتفعيل Index Only Scans على استعلامات القوائم الساخنة.
  • راقب pg_stat_user_indexes دورياً واحذف الفهارس ذات الصفر عمليات مسح.
  • لا تثق بخطط الاستعلام في بيئة التطوير لتقييم أداء الإنتاج؛ الجداول الصغيرة تُعطي نتائج مختلفة.

هل تواجه مشاكل في أداء قاعدة البيانات؟

فريق Voxire يبني ويُشغّل أنظمة SaaS مبنية على Go وPostgreSQL للشركات في لبنان ومنطقة الشرق الأوسط. إذا كانت مشاكل الأداء تُعيق تطوير منتجك، نساعدك في تشخيص السبب الجذري وتنفيذ الحل الصحيح.

https://voxire.com/get-a-quote/

العودة إلى المدونة
Chat on WhatsApp