0Pricing
SQL Interview Prep · درس

الفهارس التغطوية وعمليات Index-Only Scan

تضمين الأعمدة كي لا يضطر الاستعلام إلى الوصول إلى كومة الجدول

الفهارس التغطوية وعمليات Index-Only Scan درس مجاني في SQL Interview Prep على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.

استرجاع مفهوم جلب heap

تعلّمت سابقًا أن B-Tree العادي يخزّن الأعمدة المفهرسة فقط، بالإضافة إلى مؤشر إلى الصف؛ لذلك، بعد أن يعثر الفهرس على الصفوف المطابقة، يظل المحرك مضطرًا إلى الانتقال إلى الجدول لقراءة الأعمدة الأخرى. يُسمّى هذا الانتقال جلب heap، وهو التكلفة التي صُمّم الفهرس المغطي لإلغائها.

يسأل المحاورون عن الفهارس المغطية ليروا ما إذا كنتم تفهمون سبب قدرة الفهرس على الإجابة عن الاستعلام بالكامل من دون الوصول إلى الجدول.

ما المقصود بالتغطية

يُقال إن الفهرس يغطي استعلامًا عندما يكون كل عمود يحتاج إليه الاستعلام، في SELECT وWHERE وORDER BY وGROUP BY، موجودًا في الفهرس نفسه.

عند تحقق ذلك، يقرأ المحرك الفهرس فقط ولا يزور الجدول أبدًا. يطلق PostgreSQL على ذلك اسم Index-Only Scan، بينما تسميه SQL Server وغيرها فهرسًا مغطّيًا. وتتمثل الفائدة في تقليل قراءات الصفحات وتسريع الاستعلامات.

مثال تطبيقي: استعلام مغطّى

لنفترض أن الاستعلام يحتاج فقط إلى customer_id وorder_date. يحتوي فهرس مركب على هذين العمودين تحديدًا، لذلك يتضمن كل ما يطلبه الاستعلام ويمكن الإجابة عنه من الفهرس وحده.

CREATE INDEX idx_orders_cust_date
  ON orders (customer_id, order_date);

-- Covered: both selected columns are in the index
SELECT customer_id, order_date
FROM orders
WHERE customer_id = 42;

عمود إضافي واحد يزيل التغطية

أضف عمودًا لا يحتويه الفهرس، فتفقد التغطية ويضطر المحرك إلى جلب heap للحصول عليه.

العمود total غير موجود في الفهرس؛ لذلك، رغم أن customer_id هو الذي يقود عملية البحث، يتسبب كل صف مطابق في جلب heap لقراءة total.

-- NOT covered: total is not in the index, forces heap fetches
SELECT customer_id, order_date, total
FROM orders
WHERE customer_id = 42;

عبارة INCLUDE

يمكنكم إضافة total بوصفه عمود المفتاح الرابع، لكن إذا لم تكونوا تستخدمونه للتصفية أو الفرز مطلقًا، فذلك يهدر مساحة في ترتيب الفرز داخل الشجرة. والأداة الأنظف هي INCLUDE، المدعومة في PostgreSQL وSQL Server؛ إذ تخزّن الأعمدة الإضافية في الأوراق فقط بوصفها بيانات حمولة، لا جزءًا من مفتاح الفرز.

وهكذا يصبح الاستعلام مغطّى من دون تضخيم الجزء القابل للبحث من الفهرس.

CREATE INDEX idx_orders_cust_date_inc
  ON orders (customer_id, order_date)
  INCLUDE (total);

-- Now covered: total is carried in the leaf
SELECT customer_id, order_date, total
FROM orders
WHERE customer_id = 42;

أعمدة المفتاح مقابل الأعمدة المضمّنة

تمييز دقيق يترك انطباعًا جيدًا لدى المحاورين:

  • أعمدة المفتاح تحدد ترتيب الفرز، ويمكن استخدامها للبحث والمسح النطاقي. وهي تلتزم بقاعدة البادئة اليسرى.
  • الأعمدة المضمّنة تُخزَّن في الأوراق فقط بوصفها بيانات إضافية؛ ولا يمكن البحث فيها، لكنها تتيح للفهرس تغطية عدد أكبر من الاستعلامات.

قاعدة عامة: الأعمدة التي تُجرون التصفية أو الفرز بناءً عليها توضع في المفتاح، أما الأعمدة التي تعيدونها فقط فتوضع في INCLUDE.

MySQL/InnoDB: أثر التجميع

أظهروا وعيًا بالاختلافات بين اللهجات. تكون جداول InnoDB (في MySQL) مجمّعة حسب المفتاح الأساسي؛ إذ تحمل الفهارس الثانوية ضمنيًا أعمدة المفتاح الأساسي. لذلك يغطي الفهرس الثانوي تلقائيًا أي استعلام يحدد فقط الأعمدة المفهرسة بالإضافة إلى أعمدة المفتاح الأساسي، من دون الحاجة إلى عبارة INCLUDE، إذ لا يدعم MySQL INCLUDE.

مفهوم التغطية عام في كل الأنظمة؛ لكن الصياغة والأعمدة التي تأتي ضمنيًا تختلف باختلاف المحرك.

التحقق من Index-Only Scan

أثبت التغطية باستخدام EXPLAIN. في PostgreSQL، تُظهر عقدة الخطة Index Only Scan بدلًا من Index Scan. راقبوا ظهور Heap Fetches: 0 في EXPLAIN (ANALYZE)، فهذه هي العلامة القاطعة على عدم حدوث أي وصول إلى الجدول.

إذا توقعتم تنفيذ index-only لكنكم رأيتم Index Scan مع عمليات جلب من heap، فهذا يعني أن أحد الأعمدة المحددة غير موجود في الفهرس.

EXPLAIN (ANALYZE)
SELECT customer_id, order_date, total
FROM orders
WHERE customer_id = 42;
-- Look for: Index Only Scan ... Heap Fetches: 0

ملاحظة خريطة الرؤية في Postgres

نقطة دقيقة في Postgres تستحق علامة إضافية: قد يظل Index-Only Scan يصل إلى heap إذا لم تكن الصفحة معلّمة بأنها مرئية بالكامل في خريطة الرؤية. بعد إجراء تحديثات مكثفة، شغّلوا VACUUM حتى تصبح خريطة الرؤية محدثة؛ وإلا سترتفع قيمة Heap Fetches وتتراجع فائدة «الفهرس فقط».

-- Keeps the visibility map fresh so index-only scans stay heap-free
VACUUM ANALYZE orders;

متى لا ينبغي إنشاء فهرس تغطية عريض

الفهارس المغطية ليست مجانية. إذ تؤدي إضافة أعمدة كثيرة إلى INCLUDE إلى جعل الفهرس كبيرًا، فتستهلك ذاكرة التخزين المؤقت وتبطئ عمليات الكتابة، لأن كل كتابة ذات صلة تحدّث الفهرس. اذكروا المفاضلات التالية بوضوح:

  • ممتازة للاستعلامات القرائية الضيقة والمهمة والمتكررة بكثرة.
  • سيئة عندما تُستخدم كمستودع لكل عمود «تحسبًا للحاجة إليه».

غطّوا الاستعلام المهم، لا الصف بأكمله.

كيف تصوغون الإجابة في المقابلة

خلاصة واضحة:

«يحتوي الفهرس المغطي على كل عمود يلمسه الاستعلام، لذلك يجيب المحرك عنه من الفهرس وحده، عبر Index-Only Scan، متجاوزًا جلب heap. أضع الأعمدة التي يُبحث فيها ضمن المفتاح، والأعمدة التي تُعاد فقط ضمن INCLUDE، وأتحقق من أن Heap Fetches تساوي صفرًا باستخدام EXPLAIN ANALYZE، وأُبقي الفهرس ضيقًا لحماية سرعة الكتابة.»

تحقق سريع

حلّلوا التغطية والمكان المناسب لكل عمود.

مراجعة: الفهارس المغطية

أهم النقاط:

  • يُقال إن الفهرس يغطي استعلامًا عندما يحتوي على كل الأعمدة التي يحتاج إليها الاستعلام، مما يتيح تنفيذ Index-Only Scan من دون جلب heap.
  • تقود أعمدة المفتاح عمليات البحث، وتلتزم بقاعدة البادئة اليسرى؛ أما أعمدة INCLUDE فهي بيانات حمولة موجودة في الأوراق فقط لتوفير التغطية.
  • تتضمن الفهارس الثانوية في InnoDB المفتاح الأساسي ضمنيًا.
  • تحققوا باستخدام EXPLAIN (ANALYZE) وراقبوا Heap Fetches؛ وفي Postgres حافظوا على تحديث VACUUM.
  • أبقوا الفهارس المغطية ضيقة لحماية أداء الكتابة.

التالي: الجانب الآخر، أي الحالات التي تضر فيها الفهارس فعلًا.

الأسئلة الشائعة

هل درس «الفهارس التغطوية وعمليات Index-Only Scan» مجاني؟

نعم — نص درس «الفهارس التغطوية وعمليات Index-Only Scan» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.

ماذا ستتعلم في «الفهارس التغطوية وعمليات Index-Only Scan»؟

تضمين الأعمدة كي لا يضطر الاستعلام إلى الوصول إلى كومة الجدول تتمرن على SQL Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ SQL Interview Prep؟

لا تُشترط خبرة سابقة. SQL Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «الفهارس التغطوية وعمليات Index-Only Scan»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس SQL Interview Prep هذا؟

نعم. كل درس في SQL Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. فهارس B-Tree وكيف تساعد
  2. ترتيب أعمدة الفهرس المركب
  3. الفهارس التغطوية وعمليات Index-Only Scan
  4. متى تضر الفهارس: عمليات الكتابة والانتقائية
← العودة إلى SQL Interview Prep