بلا فهرس تقرأ قاعدة البيانات كل صفّ لتجيب سؤالًا. ومع الفهرس الصحيح تقفز إلى الجواب مباشرةً. والفرق على جدول كبير بين ثوانٍ وميكروثوانٍ — والفهرس الخاطئ أسوأ من لا فهرس، لأنه يكلّف الكتابة ولا يعطي شيئًا.
افهرس ما تُرشِّح به
شرط WHERE، ثم ORDER BY، ثم أعمدة الوصل. لا ما تختاره في SELECT — فليس ذلك ما يستعمله البحث.
SELECT * FROM orders WHERE customer_id = 42 ORDER BY created_at DESC;
CREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at);
والترتيب يهمّ في الفهرس المركّب
الفهرس المركّب يُستعمل من اليسار إلى اليمين، كدليل هاتف مرتَّب باللقب ثم الاسم. ومرتَّبًا هكذا تستطيع أن تجد كل من لقبه عليّ؛ ولا تستطيع أن تجد كل من اسمه الأوّل محمّد.
- الفهرس
(customer_id, created_at)يخدم ترشيحًا على customer_id، وعلى الاثنين معًا. - ولا يخدم ترشيحًا على created_at وحده.
- ضع العمود الذي ترشّح به تطابقًا أوّلًا، والمدى أو الترتيب ثانيًا.
وأثبت أنه يُستعمل
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;
القيمة type: ref أو const تعني أن الفهرس مستعمَل. أمّا type: ALL فتعني مسحًا كاملًا وأن الفهرس مُتجاهَل — وغالبًا لأن العمود ملفوف داخل دالّة.
فالشرط
WHERE DATE(created_at) = "2026-01-01" لا يستطيع استعمال فهرس على created_at: إذ يجب أن تعمل الدالّة على كل صفّ أوّلًا. اكتبه مدىً بدلًا من ذلك: created_at >= "2026-01-01" AND created_at < "2026-01-02".ولماذا لا تفهرس كل شيء
- كل فهرس يُحدَّث مع كل INSERT وUPDATE وDELETE. وعشرة فهارس تجعل الكتابة أبطأ عدّة أضعاف.
- وتأخذ مساحةً من القرص، أحيانًا أكثر من الجدول نفسه.
- ويصير أمام المخطِّط خياراتٌ أكثر، فيختار أحيانًا أسوأها.
أضف الفهرس الذي سمّاه سجلّ البطء، وقِس، وتوقّف. فإضافة الفهارس على سبيل التخمين هي الطريقة التي تبطؤ بها قاعدة بيانات وهي تبدو وكأنها ضُبطت.
