Lesson 6 / الدرس 6
What an index actually is / ما الفهرس فعلًا
An index is a second copy of one or two columns, kept in order, with a pointer back to the row. Everything an index can and cannot do follows from the words "kept in order", and reasoning from those three words gets you further than memorising rules.
الفهرس نسخة ثانية من عمود أو عمودين، محفوظة مرتّبة، ومعها مؤشر إلى الصف. وكل ما يستطيعه الفهرس وما لا يستطيعه يتبع كلمتَي «محفوظة مرتّبة»، والاستدلال من تلك الكلمات يبلغ بك أبعد من حفظ القواعد.
Think of the index at the back of a book. It is not the book; it is a sorted list of terms with page numbers. You use it by knowing the beginning of the word you want — which is why you can find "normalisation" in a second and cannot find "every word ending in -ation" at all. A database index works the same way, for the same reason.
CREATE INDEX bookings_guest ON bookings (guest_id);
-- What now exists, conceptually: guest_id in order, each pointing back.
--
-- guest_id | row
-- ---------+-----
-- 12 | ->
-- 12 | ->
-- 41 | ->
-- 42 | -> the database jumps straight here
-- 42 | -> reads while the value still matches
-- 57 | -> and stops
-- Which is why this is now fast:
SELECT * FROM bookings WHERE guest_id = 42;
-- And why this is too. A sorted list gives you ranges for free.
SELECT * FROM bookings WHERE guest_id BETWEEN 40 AND 50;
ORDER BY guest_id can also use this index instead of sorting the results afterwards. ORDER BY guest_id على استخدام هذا الفهرس بدل ترتيب النتائج بعدها.Two columns, and why the order of them matters
CREATE INDEX bookings_guest_date ON bookings (guest_id, starts_on);
-- Sorted by guest_id first, then by starts_on within each guest — exactly
-- like a phone book sorted by surname, then first name.
SELECT * FROM bookings WHERE guest_id = 42; -- uses it
SELECT * FROM bookings WHERE guest_id = 42 AND starts_on > '..'; -- uses it
SELECT * FROM bookings WHERE starts_on > '2026-01-01'; -- CANNOT
-- The last one is the phone book question: find everyone called Sara,
-- when the book is ordered by surname. You are back to reading all of it.
(guest_id, starts_on) makes a separate index on guest_id redundant, and does nothing at all for a query about dates alone. (guest_id, starts_on) يجعل فهرسًا منفصلًا على guest_id زائدًا، ولا يفعل شيئًا البتة لاستعلام عن التواريخ وحدها.The one that surprises people
If an index holds every column a query asks for, the database can answer from the index alone and never touch the table. That is a covering index, and it is often the difference between fast and instant — the second read, the one that fetches the actual row, is usually the expensive half. It is also the honest argument against SELECT *: asking for columns you do not need is what stops the index covering you.
SELECT *: فطلب أعمدة لا تحتاجها هو ما يمنع الفهرس من تغطيتك.status = 'confirmed'، فالقفز إلى الفهرس ثم جلب نصف الجدول صفًّا صفًّا أبطأ من قراءة الجدول مباشرة — إذ تكلّف القراءات المتناثرة أكثر من المتتابعة. والفهرس يستحق موضعه بالتضييق كثيرًا، والرايةُ بقيمتين لا تضيّق شيئًا تقريبًا.Check yourself / اختبر نفسك
1. Why can an index not answer WHERE name LIKE '%hassan'?
Everything an index can and cannot do follows from "kept in order". Reasoning from that gets you further than memorising which queries are fast.
2. You have an index on (guest_id, starts_on). Which query cannot use it?
A composite index is usable from the left only. Asking about the second column alone is the phone-book question: find everyone called Sara, in a book ordered by surname.
3. Why might the database ignore an index on a status column with two values?
Scattered reads cost more than sequential ones. An index earns its place by narrowing a lot, and the database refusing to use one is usually it being right.
Score / النتيجة: 0 / 3