الفهارس Indexes في SQL


يا هلا والله بالجميع! اليوم بنتكلم عن شي أساسي ومهم جداً في قواعد البيانات: الفهارس أو الـ Indexes. لا تفكر كثير، الموضوع أبسط مما تتخيل بس تأثيره على أداء قاعدة البيانات عندك خرافي.

إيش هي الفهارس (Indexes)؟

بكل بساطة، الفهرس في قاعدة البيانات زي فهرس الكتاب بالضبط. لما تدور على معلومة معينة في كتاب، ما تقعد تقلب صفحة صفحة صح؟ تروح للفهرس، تشوف الموضوع اللي تبغاه، وهو يعطيك رقم الصفحة. نفس الفكرة بالضبط في الـ SQL.

لما تسوي استعلام (query) وتطلب بيانات معينة، قاعدة البيانات بدال ما تمر على كل صف (row) في الجدول عشان تلقى اللي تبغاه، إذا كان عندك فهرس، بتروح للفهرس على طول، وهذا يخلي عملية البحث أسرع بمليون مرة. يعني تختصر وقت وجهد على السيرفر بشكل مو طبيعي.

أنواع الفهارس الأساسية

فيه نوعين رئيسيين لازم تعرفهم:

1. Clustered Index (الفهرس العنقودي):

  • هذا الفهرس يحدد الترتيب الفعلي للبيانات المادية في الجدول. يعني البيانات نفسها تكون مرتبة بناءً على هذا الفهرس.
  • كل جدول يقدر يكون عنده فهرس عنقودي واحد فقط. فكر فيها كأن الكتاب مترتب أبجدياً بأسماء المؤلفين. ما تقدر ترتبه بأسماء المؤلفين وبتواريخ النشر في نفس الوقت!
  • عادةً يكون على العمود اللي تحدده كـ PRIMARY KEY (المفتاح الأساسي)، لأنه هو الأنسب لترتيب البيانات.

2. Non-Clustered Index (الفهرس غير العنقودي):

  • هذا الفهرس ما يغير الترتيب المادي للبيانات في الجدول. بدال كذا، يسوي نسخة مرتبة من العمود (أو الأعمدة) اللي تحددها، ومعه مؤشرات (pointers) للصفوف الأصلية.
  • تقدر تسوي عدة فهارس غير عنقودية على الجدول الواحد.
  • فكر فيها كأنها فهارس إضافية في آخر الكتاب: فهرس للمصطلحات، فهرس للأماكن، إلخ. كل فهرس يعطيك صفحة المعلومة الأصلية.

متى تستخدم الفهارس؟

استخدمها بحكمة، مو على كل عمود! هنا بعض السيناريوهات المثالية:

  • الـ PRIMARY KEY والـ FOREIGN KEY (المفاتيح الأساسية والأجنبية). هذي دايماً لازم تكون مفهرسة.
  • الأعمدة اللي تستخدمها كثير في جمل WHERE (للشروط).
  • الأعمدة اللي تستخدمها في JOIN (للربط بين الجداول).
  • الأعمدة اللي تستخدمها في ORDER BY (للترتيب) أو GROUP BY (للتجميع).
  • الأعمدة اللي فيها بيانات فريدة (unique) أو شبه فريدة.

متى ما تستخدم الفهارس؟

الفهارس مو سحر، لها تكلفتها! لا تستخدمها على:

  • الجداول الصغيرة جداً (أقل من كم ألف صف). الفائدة بتكون ضئيلة وقد تكون سلبية.
  • الأعمدة اللي تتحدث (update) كثير جداً أو تُضاف (insert) أو تُحذف (delete) فيها بيانات بشكل مكثف. كل عملية تحديث/إضافة/حذف تتطلب تحديث الفهرس أيضاً، وهذا يقلل الأداء.
  • الأعمدة اللي فيها قيم مكررة كثير جداً (Low cardinality)، زي عمود gender (ذكر/أنثى). قاعدة البيانات ممكن تلقى اللي تبغاه أسرع بمسح الجدول كامل.
  • الأعمدة اللي ما تستخدمها في البحث أو الترتيب أبداً.

ملاحظة مهمة: الفهارس تسرّع عمليات القراءة (SELECT) بشكل كبير، لكنها تبطّئ عمليات الكتابة (INSERT, UPDATE, DELETE) لأنها تحتاج تعديل الفهرس مع البيانات الأصلية. لازم توازن بين الاثنين.

كيف تسوي فهرس؟ (CREATE INDEX)

بسيط جداً، هذا هو الكود الأساسي:

CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX index_name
ON table_name (column1 [ASC|DESC], column2 [ASC|DESC], ...);
  • UNIQUE: إذا تبغى تتأكد إن كل قيمة في العمود (أو الأعمدة) اللي تسوي عليها الفهرس تكون فريدة.
  • CLUSTERED | NONCLUSTERED: تحدد نوع الفهرس. إذا ما حددت، الديفولت يكون NONCLUSTERED في أغلب قواعد البيانات (ما عدا الـ PRIMARY KEY اللي يكون CLUSTERED تلقائياً).
  • index_name: اسم الفهرس (اختياري بس يفضل تسميه باسم واضح).
  • table_name: اسم الجدول.
  • column1, column2, ...: الأعمدة اللي تبغى تسوي عليها الفهرس. تقدر تحط عمود واحد أو أكثر.
  • ASC|DESC: تحدد ترتيب الفهرس تصاعدي أو تنازلي.

مثال: عندي جدول Users وفيه عمود Email أبغى أسوي عليه فهرس غير عنقودي عشان البحث بالايميل يكون سريع، وأبغاه يكون فريد:

CREATE UNIQUE NONCLUSTERED INDEX IX_Users_Email
ON Users (Email ASC);

مثال 2: جدول Orders وعمود OrderDate أبغى أسوي عليه فهرس عشان أسرّع استعلامات البحث والترتيب حسب تاريخ الطلب:

CREATE NONCLUSTERED INDEX IX_Orders_OrderDate
ON Orders (OrderDate DESC);

كيف تحذف فهرس؟ (DROP INDEX)

إذا سويت فهرس وطلع ما منه فايدة أو قاعد يبطئ لك الدنيا، تقدر تحذفه بسهولة:

DROP INDEX index_name ON table_name;
-- أو في بعض قواعد البيانات زي SQL Server:
DROP INDEX table_name.index_name;

مثال: حذف الفهرس اللي سويناه على عمود الايميل في جدول Users:

DROP INDEX IX_Users_Email ON Users;

خلاصة الكلام

الفهارس أداة قوية جداً لتحسين أداء قواعد البيانات، خصوصاً مع الجداول الكبيرة والاستعلامات المعقدة. لكن استخدامها يبغى له فهم وتوازن. لا تبالغ في استخدامها، ودايماً راقب أداء قاعدة البيانات بعد إضافة أي فهرس جديد. بالتوفيق!