حين تجعل إضافة فهرس الأمور أبطأ
لجدول الأرقام اليومية مفتاح واحد: العداد والتاريخ معًا. وفي الكود خمسة مواضع تطرح عليه سؤالًا مختلفًا — لا «هذا العداد عبر الزمن» بل «كل العدادات في هذه التواريخ». معرض الصفحة الرئيسية، وقائمة الصدارة، وخريطة الموقع، ومخطط 90 يومًا، وأرقام الحالة. ومن دون فهرس على عمود التاريخ، يقرأ كلٌّ منها صفوف الجدول كلها البالغة 114,113.
إضافة هذا الفهرس تجعل المعرض أسرع بعشر مرات. ومع ذلك لم يُضف. وإليك القياس الذي حسم الأمر.
استعلام واحد صار أسرع بكثير
يطلب المعرض العدادات التي كانت نشطة اليوم. ومن دون فهرس على التاريخ يمسح الجدول كله؛ ومع الفهرس يبحث عن تاريخ واحد ويقرأ 443 صفًا. فصارت 61.5 مللي ثانية 6.1. هذه ليست نتيجة خفية، ولو كانت الشيء الوحيد الذي قيس، لكان الفهرس في قاعدة البيانات الآن.
استعلامان صارا أبطأ
تطلب خريطة الموقع أربعة عشر يومًا، وصارت أبطأ بنسبة 19%. وتطلب أرقام الحالة سنة، وصارت أبطأ بنسبة 10%. وفي الحالتين انتقل مُحسِّن الاستعلامات من المفتاح الأساسي إلى الفهرس الجديد، واتخذ خيارًا أسوأ.
هذا هو الجزء الجدير بالفهم، لأنه ليس خللًا في المُحسِّن. فقراءة نطاق عبر فهرس ثانوي تعني إيجاد الصفوف المطابقة في الفهرس ثم جلب كل صف منها من الجدول. وهذه صفقة رابحة لشريحة ضيقة. أما لأربعة عشر يومًا من أصل ثلاثة عشر شهرًا فهي لا تزال صفوفًا كثيرة تُجلب واحدًا تلو الآخر، والمسح المباشر للجدول — أي قراءته بترتيبه الفعلي، وهو ما تحبه الأقراص وذاكرات التخزين المؤقت — يتفوق عليها. المُحسِّن لا يعرف ذلك. إنه يرى نطاقًا وفهرسًا فيأخذه.
لا توجد طريقة لقول «استخدم هذا الفهرس للمعرض فقط». فالفهرس متاح لكل استعلام يمس العمود، وسيستخدمه المُحسِّن حيثما قالت تقديراته إن عليه ذلك. وإضافة فهرس هي تغيير لكل استعلام على ذلك الجدول، لا للاستعلام الذي أُريد له فقط.
في المجموع: لا شيء
عبر الاستعلامات الخمسة كلها، صارت 555 مللي ثانية 524. أي تحسن بمقدار 1.1×، وهو على خادم صغير يقدّم هذه الصفحات من ذاكرة تخزين مؤقت على أي حال لا يستحق تغيير بنية قاعدة البيانات.
يبدو أن مخطط 90 يومًا تحسن بنسبة 9%. لكنه لا يُحتسب، ومن المفيد قول السبب. فقد قيس كل استعلام ثلاث مرات: من دون الفهرس، ثم معه، ثم من دونه مرة أخرى. وإذا لم يأتِ التشغيل الثاني من دون الفهرس قريبًا من الأول، فالفرق سببه الجهاز لا التغيير. وفي مخطط 90 يومًا اختلف التشغيلان من دون الفهرس بنسبة 13.8% — أي أكثر من الأثر المزعوم. لذا فهذا الصف لا يقيس شيئًا، ويُبلَّغ عنه على أنه لا شيء.
كيف قيس هذا، ولماذا يهم ذلك
ليس على الجدول الحي. فالسكربت ينسخه، ويعمل على النسخة، ثم يحذفها في النهاية. إضافة فهرس إلى جدول قيد الإنتاج لمعرفة ما سيحدث لا تنفع إلا مرة واحدة لكل مفاجأة.
الاستعلامات هي الحقيقية، مأخوذة من الكود، بما في ذلك الربط بجدول العدادات. وقد استخدمت نسخة سابقة من هذا الاختبار بديلًا مبسطًا، فأنتجت إجابة أكثر إثارة بكثير: أسرع بعشرين مرة. لكن الاستعلام المبسط لم يكن استعلامًا يشغّله أي شيء فعلًا.
ما كان الرقم سيكون عليه
لو قيس هذا بالطريقة المعتادة — خذ الاستعلام الذي يبدو بطيئًا، وقِس زمنه قبل التغيير وبعده — لكان الجواب «أسرع بعشر مرات، اعتمده». ولأُضيف الفهرس، ولصار المعرض أسرع، ولصارت خريطة الموقع وصفحة الحالة أبطأ، ولما ربط أحد بين الأمرين، لأن أحدًا لم يكن يراقبهما.
هذه هي الصورة العامة. لا يمكن تقييم تغيير في بنية تحتية مشتركة بناءً على الحالة التي دفعت إليه. فالسؤال ليس «هل يساعد هذا الشيء الذي أنظر إليه؟» بل «ما الذي يمس هذا أيضًا، وماذا يحدث له؟».
هناك صيغة قد تنجح: فهرس يضم العمودين، التاريخ أولًا، بحيث يمكن الإجابة عن استعلام المعرض من الفهرس وحده دون الرجوع إلى الجدول. وقد يتجنب أيضًا إغراء المُحسِّن في النطاقات الأوسع. لم يُقس ذلك بعد، لذا فهو ليس توصية — بل هو الشيء التالي الذي سيُجرَّب على النسخة.