الاستجابة البطيئة ليست دعوة لإضافة فهرس لكل عمود. قد يكون السبب تحميل علاقات كثيرة، أو إرجاع آلاف الصفوف، أو انتظار قفل، أو استعلام لا يستفيد من الفهرس الموجود. ابدأ بنص الاستعلام والقيم المعتادة وحجم البيانات، ثم افحص خطة التنفيذ قبل اتخاذ قرار.
صف نمط الوصول
لنفترض لوحة طلبات تعرض آخر خمسين طلبًا لتاجر واحد وحالة محددة. السؤال ليس «هل tenant_id مفهرس؟» فقط، بل كيف تتعاون شروط التصفية مع الترتيب والحد. دوّن الاستعلامات الأكثر تكرارًا والمكلفة، وعدد الصفوف المتوقع، وحجم الرد. أحيانًا حذف أعمدة غير مطلوبة أو معالجة N+1 يحقّق التحسين المطلوب دون فهرس جديد.
SELECT id, created_at, total
FROM orders
WHERE tenant_id = :tenant AND status = :status
ORDER BY created_at DESC, id DESC
LIMIT 50;
-- Candidate to evaluate, not a universal index:
CREATE INDEX orders_tenant_status_recent
ON orders (tenant_id, status, created_at DESC, id DESC);افهم ترتيب الأعمدة
الفهرس المقترح يعكس مساواة العميل والحالة ثم ترتيب الزمن والمعرّف. إضافة id تمنح ترتيبًا مستقرًا عند تساوي الوقت. لكنه قد لا يخدم بنفس الكفاءة قائمة لا تصفّي بالحالة أو تقريرًا يجمع كل العملاء. سلوك الفهارس يعتمد على نوعها وإصدار PostgreSQL وتوزيع البيانات؛ لا تحوّل قاعدة مبسّطة عن «العمود الأول» إلى حكم على كل خطة ممكنة.
اقرأ EXPLAIN بعين القياس
ابدأ بالخطة، ثم استخدم EXPLAIN ANALYZE بحذر في بيئة مناسبة لأنه ينفّذ الاستعلام فعليًا. قارن الصفوف المقدّرة بالفعلية، والوقت، وعمليات الفرز والقراءة. الاستعلام الذي يقرأ نسبة كبيرة من الجدول قد يكون المسح التسلسلي له منطقيًا. اسم Index Scan وحده لا يثبت أن الخطة أسرع للمستخدم.
لا تنسَ تكلفة الكتابة
كل فهرس إضافي يحتاج مساحة وعملًا عند تغيّر البيانات ذات الصلة. في نظام لوجستي كثير التحديث، قد تسرّع لوحة واحدة وتبطئ إدخال الحالات. قِس زمن الكتابة ومساحة الفهرس ووقت الصيانة. راجع الفهارس المتداخلة، لكن لا تحذف فهرسًا لمجرّد انخفاض استخدامه خلال فترة قصيرة؛ قد يخدم تقريرًا دوريًا أو قيدًا مهمًا.
اختبر بيانات قريبة من الواقع
بيانات الاختبار المتجانسة قد تخفي انحرافًا واضحًا في الإنتاج: تاجر ضخم وآلاف تجّار صغار، أو حالة يملكها معظم الطلبات. اختبر القيم الشائعة والحالات الطرفية. راقب أيضًا زمن الشبكة ووقت تحويل النتائج إلى JSON حتى لا تنسب كل بطء إلى قاعدة البيانات.
خطة تطبيق قابلة للرجوع
احتفظ بقياسات قبل التغيير، ثم أضف الفهرس بطريقة تناسب حركة الإنتاج وإمكانات الإصدار. راقب القراءة والكتابة بعد الإطلاق، ودوّن الاستعلام الذي يبرّر وجود الفهرس. الفهرسة الجيدة قرار قابل للتحقّق، وليست مجموعة أعمدة تُضاف احتياطًا.
سيناريو عملي: تاجر ضخم بين آلاف التجّار
قد تعطي تجربة على تاجر صغير نتيجة ممتازة، بينما تظل صفحة تاجر كبير بطيئة. احفظ مجموعة معرّفات اختبار تمثّل حجم البيانات وتوزيع الحالات، وقارن عدد الصفوف التي تقرؤها الخطة للوصول إلى الخمسين المطلوبة. إذا كانت المشكلة في صفحة متأخرة تستخدم offset كبيرًا، راجع طريقة التصفح نفسها؛ الفهرس وحده قد لا يزيل العمل الذي يفرضه تخطّي صفوف كثيرة.
وثّق قرار الفهرسة
اكتب الاستعلام الذي يخدمه الفهرس، وحجم البيانات أثناء القياس، والقيم المستخدمة، ونتيجة القراءة والكتابة قبل الإضافة وبعدها. حدّد من يراجع أثره عند تغيّر الاستعلام أو إضافة فلتر جديد. هذا السجل يمنع بقاء فهرس مكلف لميزة لم تعد تستخدمه، ويساعد الفريق على فهم سبب ترتيب الأعمدة بدل تكرار فهرس قريب منه باسم مختلف.
المراجع الرسمية
تدعم هذه المراجع سلوك الأدوات المذكورة. الأمثلة وقرارات التصميم توضيحية، ويجب تكييفها مع متطلبات المشروع وإصداراته.
إعداد: Noor Yasser
تعمل على تحدٍ تقني مشابه؟
أساعد الفرق على تحويل القرار المعماري إلى نطاق واضح وتنفيذ يمكن تشغيله ومراجعته بثقة.




