استعلام PostgreSQL بطيء؟ حسّنه بالأرقام بدل التخمين
هتطلع من المقال بخطة واضحة لتقليل زمن Query بطيئة في PostgreSQL من حوالي 1800ms إلى 230ms في سيناريو واقعي، بدون ما تبدأ بترقية السيرفر.
مستوى القارئ: متوسط
المشكلة باختصار
لو عندك endpoint بيعرض آخر طلبات عميل معيّن، وبدأ ياخد ثانيتين تحت الضغط، أسوأ رد فعل هو إنك تزود CPU أو RAM فورًا. الطريقة دي بتفشل لأن المشكلة غالبًا في شكل الوصول للبيانات، مش في حجم السيرفر.
الافتراض هنا إن عندك جدول orders فيه حوالي 1.2 مليون صف، وموقع بيخدم 50K زائر يوميًا. الـ API المطلوب بيرجع آخر 50 طلب لعميل واحد. القياس الأولي: p95 latency = 1800ms، وقراءة حوالي 42000 shared blocks. بعد فهرس مناسب وقياس جديد وصلنا إلى p95 = 230ms وقراءة حوالي 4800 shared blocks. الأرقام مثال عملي، ولازم تعيد القياس على بياناتك.
ابدأ من الاستعلام الحقيقي
ركز: لا تبدأ من الإحساس. ابدأ من query فعلاً بتتكرر وبتستهلك وقت. أداة pg_stat_statements في PostgreSQL بتجمع إحصائيات تنفيذ الاستعلامات، وده يخليك تشوف الاستعلامات الأعلى زمنًا وعدد مرات تنفيذ. حسب توثيق PostgreSQL، الإضافة تحتاج shared_preload_libraries وتتبّع إحصائيات التخطيط والتنفيذ.
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT
calls,
round(mean_exec_time::numeric, 2) AS mean_ms,
round(total_exec_time::numeric, 2) AS total_ms,
query
FROM pg_stat_statements
WHERE query ILIKE '%orders%'
ORDER BY total_exec_time DESC
LIMIT 5;لو ظهر الاستعلام ده في الأعلى، يبقى عندك هدف واضح:
SELECT id, status, total_cents, created_at
FROM orders
WHERE tenant_id = $1
ORDER BY created_at DESC
LIMIT 50;اقرأ الخطة قبل ما تضيف فهرس
EXPLAIN (ANALYZE, BUFFERS) بيشغّل الاستعلام فعليًا ويعرض زمن التنفيذ وعدد الصفوف وقراءات الـ buffers. PostgreSQL نفسه يوضح إن ANALYZE يعرض الأرقام الحقيقية، وإن BUFFERS يوضح استخدام الذاكرة والقراءة من التخزين.