متى تضر الفهارس: عمليات الكتابة والانتقائية
تضخيم عمليات الكتابة وسبب عدم جدوى الفهرس على عمود منخفض الانتقائية
متى تضر الفهارس: عمليات الكتابة والانتقائية درس مجاني في SQL Interview Prep على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
السؤال الكامن وراء السؤال
بعد ثلاثة دروس عن أسباب فائدة الفهارس، يعكس المحاورون السؤال: «لماذا لا نفهرس كل عمود فحسب؟» يشرح المرشح القوي أن للفـهارس تكاليف حقيقية، على مستوى الكتابة وذاكرة التخزين المؤقت والتخزين، وأن بعض الفهارس قد لا يستخدمها المخطط مطلقًا.
يتناول هذا الدرس السببين الرئيسيين اللذين قد يجعل أحدهما الفهرس ضارًا: تضخيم الكتابة وانخفاض الانتقائية.
كل فهرس يبطئ عمليات الكتابة
يجب أن يظل الفهرس متزامنًا مع الجدول. فكل INSERT وكل DELETE وكل UPDATE لعمود مفهرس يجب أن يحدّث بنية الفهرس أيضًا. هذا هو تضخيم الكتابة: يتحول تغيير صف واحد إلى كتابة في الجدول، بالإضافة إلى كتابة لكل فهرس متأثر.
يدفع الجدول الذي يحتوي على ثمانية فهارس ثمنًا يقارب تسعة أضعاف عمل الكتابة في جدول غير مفهرس. وفي الجداول كثيفة الكتابة أو عالية معدل النقل، تمثل هذه تكلفة كبيرة.
مثال تطبيقي: ضريبة الكتابة
تخيلوا جدول أحداث يستقبل آلاف الصفوف في الثانية. كل فهرس إضافي يجعل كل عملية إدراج تنفذ عملًا أكبر، مثل تقسيم صفحات الفهرس وتحديث الأوراق والتنافس على ذاكرة التخزين المؤقت.
بالنسبة إلى جدول تُضاف إليه البيانات فقط وتغلب عليه الكتابة، تكون الإجابة الصحيحة غالبًا إنشاء عدد قليل من الفهارس أو عدم إنشاء أي فهرس باستثناء المفتاح الأساسي، وتنفيذ عمليات القراءة الثقيلة على نسخة متماثلة أو مستودع بيانات بدلًا من ذلك.
-- Each of these indexes adds cost to EVERY insert below
CREATE INDEX ix_events_user ON events (user_id);
CREATE INDEX ix_events_type ON events (event_type);
CREATE INDEX ix_events_ts ON events (created_at);
INSERT INTO events (user_id, event_type, created_at)
VALUES (42, 'click', now()); -- now updates table + 3 indexesمفهوم الانتقائية
الانتقائية هي مدى قدرة العمود على تمييز الصفوف، أي نسبة الصفوف التي تطابقها قيمة نموذجية. تعني الانتقائية العالية وجود عدد قليل من الصفوف لكل قيمة، مثل البريد الإلكتروني أو UUID. أما الانتقائية المنخفضة فتعني وجود صفوف كثيرة لكل قيمة، مثل قيمة منطقية أو حالة لها ثلاثة خيارات.
تكون الفهارس مفيدة في الأعمدة عالية الانتقائية، حيث يلغي البحث كل شيء تقريبًا. أما في الأعمدة منخفضة الانتقائية، فغالبًا لا تحقق الفائدة نفسها.
لماذا يكون فهرس منخفض الانتقائية عديم الفائدة
لنفترض أن قيمة is_active تساوي true لدى 90% من المستخدمين. سيعيد البحث عبر الفهرس 90% من الجدول، ومع هذا العدد الكبير من الصفوف سيجري المحرك عملية جلب من heap لكل صف، وهو أبطأ من مسح الجدول تسلسليًا في مرور واحد.
لذلك يتجاهل المخطط الفهرس بشكل صحيح وينفذ مسحًا تسلسليًا. وهكذا لا يكلّف الفهرس سوى عبء الكتابة ومساحة التخزين، من دون تقديم أي فائدة للقراءة.
-- 90% of rows match: the planner will likely skip this index
CREATE INDEX ix_users_active ON users (is_active);
SELECT * FROM users WHERE is_active = true;الحد التقريبي
قاعدة مفيدة يمكن ذكرها شفهيًا: عندما يطابق الشرط أكثر من نحو 5 إلى 20% من الجدول، يتفوق المسح التسلسلي عادةً على مسح الفهرس، لأن عمليات الجلب العشوائي من heap تكلّف أكثر من بث الصفحات بترتيبها.
تعتمد نقطة التحول الدقيقة على حجم الصفوف والتخزين المؤقت وسرعة التخزين؛ ولذلك يستخدم المخطط الإحصاءات لاتخاذ القرار، لا رقمًا ثابتًا.
الفهارس الجزئية للإنقاذ
إذا كنتم تستعلمون دائمًا عن القيم النادرة في عمود منحرف التوزيع، فإن الفهرس الجزئي في Postgres يفهرس تلك الصفوف فقط، فيكون صغيرًا وانتقائيًا ورخيص الصيانة.
إذا كانت 1% من الطلبات تحمل القيمة pending وكانت هذه الطلبات هي التي تستعلمون عنها باستمرار، فافهرسوها وحدها. يظل الفهرس صغيرًا، وسيستخدمه المخطط بسهولة.
-- Index only the rare, frequently-queried rows
CREATE INDEX ix_orders_pending
ON orders (created_at)
WHERE status = 'pending';الإحصاءات القديمة تضلل المخطط
يقرر المحسّن الاختيار بين الفهرس والمسح اعتمادًا على إحصاءات الأعمدة. وإذا كانت هذه الإحصاءات قديمة، بعد تحميل جماعي أو تحديث كبير، فقد يسيء تقدير الانتقائية ويختار خطة خاطئة.
عندما يقول المحاور «الفهرس موجود لكنه لا يُستخدم»، تتضمن الإجابة الممتازة تحديث الإحصاءات باستخدام ANALYZE قبل إلقاء اللوم على الفهرس نفسه.
ANALYZE orders; -- refresh planner statisticsطرق أخرى تضر بها الفهارس
أكملوا الإجابة بذكر التكاليف الأقل شهرة:
- التخزين وذاكرة التخزين المؤقت: تشغل الفهارس مساحة على القرص وتتنافس على الذاكرة، فتطرد صفحات بيانات مفيدة.
- الفهارس المكررة أو المتداخلة: تُصان لكنها لا تُختار مطلقًا.
- التضخم: تتجزأ أشجار B-Trees في ظل التحديثات الكثيفة، وتحتاج إلى
REINDEX. - إرباك المحسّن: تؤدي كثرة الفهارس المتشابهة إلى إبطاء التخطيط وجعله أقل قابلية للتنبؤ.
العثور على الفهارس غير المستخدمة
للدفاع عن عملية تنظيف واقعية، اذكروا أن Postgres يتتبع استخدام الفهارس. فالفهارس التي لها idx_scan = 0 مرشحة للحذف، لأنها تكلّف عمليات كتابة ومساحة تخزين من دون أن تخدم أي قراءة.
SELECT relname AS table_name, indexrelname AS index_name, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY relname;كيف تصوغون الإجابة في المقابلة
خلاصة كاملة ومتوازنة:
«تسبب الفهارس تضخيمًا للكتابة؛ فكل عملية إدراج أو تحديث أو حذف تحافظ عليها، إضافة إلى الضغط على التخزين وذاكرة التخزين المؤقت. ولا تحقق الفائدة إلا مع الشروط عالية الانتقائية؛ أما في عمود تطابق فيه معظم الصفوف، فيفضّل المخطط المسح التسلسلي بحق، ولذلك لا يكون الفهرس سوى عبء إضافي. وبالنسبة إلى الأعمدة المنحرفة التوزيع، ألجأ إلى فهرس جزئي، وأحافظ على حداثة الإحصاءات باستخدام ANALYZE، وأحذف الفهارس غير المستخدمة.»
تحقق سريع
حدّدوا الفهرس الأقل احتمالًا لأن تبرر فائدته تكلفته.
مراجعة: متى تضر الفهارس
أهم النقاط:
- يضيف كل فهرس تضخيمًا للكتابة، بالإضافة إلى تكلفة التخزين وذاكرة التخزين المؤقت.
- تفيد الفهارس في الأعمدة عالية الانتقائية؛ أما في الأعمدة منخفضة الانتقائية فيفضّل المخطط المسح التسلسلي.
- عندما تتجاوز نسبة الصفوف المطابقة نحو 5 إلى 20%، يفوز المسح عادةً.
- استخدموا فهرسًا جزئيًا للأعمدة المنحرفة التوزيع التي لا تستعلمون فيها إلا عن القيم النادرة.
- حافظوا على حداثة الإحصاءات باستخدام
ANALYZE، واحذفوا الفهارس غير المستخدمة (idx_scan = 0).
بهذا يكتمل مساق استراتيجية الفهرسة: أنشئوا الفهارس حيث تستحق تكلفتها، وأثبتوا ذلك من خلال الخطة.
الأسئلة الشائعة
هل درس «متى تضر الفهارس: عمليات الكتابة والانتقائية» مجاني؟
نعم — نص درس «متى تضر الفهارس: عمليات الكتابة والانتقائية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.
ماذا ستتعلم في «متى تضر الفهارس: عمليات الكتابة والانتقائية»؟
تضخيم عمليات الكتابة وسبب عدم جدوى الفهرس على عمود منخفض الانتقائية تتمرن على SQL Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ SQL Interview Prep؟
لا تُشترط خبرة سابقة. SQL Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «متى تضر الفهارس: عمليات الكتابة والانتقائية»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس SQL Interview Prep هذا؟
نعم. كل درس في SQL Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- فهارس B-Tree وكيف تساعد
- ترتيب أعمدة الفهرس المركب
- الفهارس التغطوية وعمليات Index-Only Scan
- متى تضر الفهارس: عمليات الكتابة والانتقائية