مقدمة في الفهارس
الفهارس عنصر مهم في تحسين قواعد بيانات MySQL. تسمح الفهارس لقاعدة البيانات بالعثور على البيانات واسترجاعها من الجداول بشكل أسرع بكثير من خلال تخزين قائمة مرتبة من القيم التي تشير إلى السجلات الكاملة.
بدون فهرس، يجب على MySQL مسح كل صف في الجدول للعثور على البيانات ذات الصلة. وهذا يمكن أن يكون بطيئًا للغاية مع نمو حجم الجداول. إضافة الفهارس المناسبة تسمح لـ MySQL بالتنقل في بيانات الجدول بطريقة أكثر كفاءة بكثير.
ومن مزايا الفهارس الرئيسية:
- عمليات بحث أسرع للصفوف والقيم المحددة
- تحسين أداء الاستعلامات المختلفة، وخاصة الـ JOINs والـ WHERE
- القدرة على تحسين استرجاع البيانات عبر جداول قاعدة البيانات الكبيرة
- عمليات الفرز والتجميع أسرع على الأعمدة المفهرسة
يدعم MySQL عدة أنواع من الفهارس لتحسين الاستعلامات بطرق مختلفة:
- NORMAL – فهرس أساسي على عمود واحد أو عدة أعمدة
- UNIQUE – يضمن تفرد القيم المفهرسة
- FULLTEXT – لتحسين البحث القائم على النصوص
- SPATIAL – للبيانات المكانية مثل المواقع
سيوفر هذا الدليل أمثلة على إنشاء واستخدام هذه الأنواع المختلفة من فهارس MySQL لتحسين أداء قاعدة البيانات.
الاتصال بـ MySQL وإعداد قاعدة بيانات عينة
قبل إظهار الفهارس ، نحتاج إلى قاعدة بيانات MySQL مع بعض البيانات العينة. فيما يلي الخطوات للاتصال بـ MySQL وإنشاء قاعدة بيانات “جهات اتصال” بسيطة:
- قم بالاتصال بخادم MySQL من سطر الأوامر باستخدام عميل mysql:
$ mysql -u root -p
- عند المطالبة، أدخل كلمة مرور مستخدم root لـ MySQL. يجب أن تكون الآن في وحدة مراقبة MySQL.
- أنشئ قاعدة بيانات جديدة تسمى
contacts
:
mysql> CREATE DATABASE contacts;
- انتقل إلى قاعدة البيانات contacts الجديدة:
mysql> USE contacts;
- أنشئ جدول
contacts
مع بعض البيانات العينة:
mysql> CREATE TABLE contacts (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
email VARCHAR(100),
phone VARCHAR(20)
);
mysql> INSERT INTO contacts (first_name, last_name, email, phone)
VALUES
('John', 'Doe', '[email protected]', '555-555-5555'),
('Jane', 'Doe', '[email protected]', '555-555-5556'),
('Bob', 'Smith', '[email protected]', '555-555-5557');
هذا ينشئ جدولًا بسيطًا لتخزين معلومات الاتصال مثل الاسم والبريد الإلكتروني ورقم الهاتف.
يمكننا التحقق من أنه نجح عن طريق استعلام الجدول:
mysql> SELECT * FROM contacts;
يجب أن يعرض ذلك البيانات العينة التي أدخلناها. لدينا الآن قاعدة بيانات وجدول جاهزان لإظهار استخدام الفهارس.
+----+------------+-----------+--------------------+---------------+
| id | first_name | last_name | email | phone |
+----+------------+-----------+--------------------+---------------+
| 1 | John | Doe | [email protected] | 555-555-5555 |
| 2 | Jane | Doe | [email protected] | 555-555-5556 |
| 3 | Bob | Smith | [email protected] | 555-555-5557 |
+----+------------+-----------+--------------------+---------------+
3 lignes trouvées (0.00 sec)
استخدام فهارس العمود الواحد
الفهرس القياسي في MySQL يفهرس عمودًا واحدًا من جدول قاعدة البيانات. هذا يسمح بعمليات البحث والفرز السريعة على هذا العمود بالتحديد.
لإضافة فهرس إلى عمود، يمكننا استخدام إعلان CREATE INDEX
:
mysql> CREATE INDEX idx_last_name ON contacts(last_name);
يضيف هذا فهرسًا يسمى idx_last_name
على عمود last_name
من جدول contacts
.
يمكن أن يحسّن فهرسة عمود last_name الاستعلامات مثل هذه التي ترشح حسب الاسم الأخير:
mysql> SELECT * FROM contacts WHERE last_name='Doe';
بدلاً من مسح كل صف، يمكن لـ MySQL البحث بسرعة في عمود last_name المفهرس للعثور على الصفوف ذات الصلة.
+----+------------+-----------+--------------------+---------------+
| id | first_name | last_name | email | phone |
+----+------------+-----------+--------------------+---------------+
| 1 | John | Doe | [email protected] | 555-555-5555 |
| 2 | Jane | Doe | [email protected] | 555-555-5556 |
+----+------------+-----------+--------------------+---------------+
2 lignes trouvées (0.00 sec)
يوضح ذلك الصفوف التي تم إرجاعها من جدول contacts حيث الاسم الأخير هو ‘Doe’. يسمح الفهرس على عمود last_name لهذا الاستعلام بالتشغيل بسرعة دون مسح الجدول بالكامل.
يمكننا إضافة فهارس مماثلة على أعمدة جدول أخرى مثل البريد الإلكتروني أو الهاتف:
mysql> CREATE INDEX idx_email ON contacts(email);
mysql> CREATE INDEX idx_phone ON contacts(phone);
هذا يسمح أيضًا بعمليات بحث سريعة حسب تلك الأعمدة.
لحذف فهرس عندما لم يعد مطلوبًا، استخدم DROP INDEX
:
mysql> DROP INDEX idx_email ON contacts;
تعمل فهارس العمود الواحد بشكل أفضل على الأعمدة المستخدمة بشكل متكرر في عمليات البحث والـ joins. لا تفهرس كل الأعمدة بشكل مفرط، لأن الفهارس تستهلك مساحة تخزين وتبطئ عمليات الكتابة مثل INSERT و UPDATE لأنه يجب تحديث الفهارس أيضًا.
استخدام الفهارس الفريدة لمنع البيانات المكررة
في كثير من الحالات، نريد منع القيم المكررة من أن تُخزن في أعمدة معينة، مثل عناوين البريد الإلكتروني أو أسماء المستخدمين. يوفر MySQL فهرس UNIQUE خاص يفرض هذا القيد:
mysql> CREATE UNIQUE INDEX idx_email ON contacts(email);
يسمح هذا الفهرس فقط بإدخال قيم بريد إلكتروني فريدة في تلك العمود. إذا حاولنا إدراج بريد إلكتروني مكرّر:
mysql> INSERT INTO contacts (first_name, last_name, email, phone)
VALUES ('Bob', 'Jones', '[email protected]', '555-555-5558');
سنحصل على خطأ:
ERROR 1062 (23000): Duplicate entry '[email protected]' for key 'idx_email'
منع الفهرس الفريد إدراج البريد الإلكتروني المكرر. هذا يساعد في فرض سلامة البيانات في الأعمدة المهمة.
مثل الفهارس الأخرى، لا يزال فهرس UNIQUE يوفر عمليات بحث سريعة حسب العمود المفهرس. التفرد هو مجرد قيد إضافي.
استخدام الفهارس على عدة أعمدة
يمكن أيضًا إنشاء فهارس تمتد عبر عدة أعمدة. هذا يسمح بتحسين الاستعلامات التي ترشح تلك الأعمدة بنفس الترتيب.
على سبيل المثال، لفهرسة كل من أعمدة الاسم الأول والأخير:
mysql> CREATE INDEX idx_name ON contacts(first_name, last_name);
يمكن أن يحسّن هذا استعلامًا مع شرط WHERE على كلا العمودين:
mysql> SELECT * FROM contacts WHERE first_name='Jane'AND last_name='Doe';
كما يعمل أيضًا للاستعلامات التي ترشح فقط العمود المفهرس الأول:
mysql> SELECT * FROM contacts WHERE first_name='Jane';
لكنه لن يحسّن استعلام يرشح فقط العمود المفهرس الثاني:
mysql> SELECT * FROM contacts WHERE last_name='Doe';
في تلك الحالة، سيتم استخدام فهرس العمود الواحد على last_name
بدلاً من ذلك.
ترتيب الأعمدة في فهرس متعدد الأعمدة مهم. تنطبق التحسينات على شروط WHERE مع مرشحات على بادئات الأعمدة المفهرسة.
سرد وإزالة الفهارس الموجودة
للمساعدة في فهم الفهارس الموجودة على جدول، يمكننا استعلام قاعدة البيانات النظامية INFORMATION_SCHEMA
:
mysql> SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA ='contacts'AND TABLE_NAME ='contacts';
سيعرض ذلك بيانات وصفية عن الفهارس على جدولنا، بما في ذلك أسماؤها وأعمدتها.
مثلاً:
+------+------------+------------+------------+--------------+-------------+----------+------------+----------+--------+------+------------+---------+---------------+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | NON_UNIQUE | INDEX_SCHEMA | INDEX_NAME | SEQ_IN_INDEX | COLUMN_NAME | COLLATION | CARDINALITY | SUB_PART | PACKED | NULLABLE | INDEX_TYPE | COMMENT |
+------+------------+------------+------------+--------------+-------------+----------+------------+----------+--------+------+------------+---------+---------------+
| def | contacts | contacts | 0 | contacts | PRIMARY | 1 | id | A | 3 | NULL | NULL | | BTREE | |
| def | contacts | contacts | 1 | contacts | idx_email | 1 | email | A | 3 | NULL | NULL | YES | BTREE | |
+------+------------+------------+------------+--------------+-------------+----------+------------+----------+--------+------+------------+---------+---------------+
عندما لم يعد الفهرس مطلوبًا، يمكننا إزالته باستخدام DROP INDEX
:
mysql> DROP INDEX idx_name ON contacts;
يمكن أن تساعد إزالة الفهارس غير المُحسّنة والمستخدمة بانتظام في تحسين أداء الكتابة وتقليل متطلبات التخزين.
الخاتمة
يوفر إضافة الفهارس تحسينات قوية لاستعلام ومعالجة البيانات في جداول MySQL. يمكن للفهارس الصحيحة أن تسرع بشكل كبير عمليات البحث والترشيح والفرز والـ joins.
بعض النقاط الرئيسية التي يجب تذكرها:
- استخدم فهارس العمود الواحد للأعمدة المرشحة بشكل متكرر
- تمنع فهارس UNIQUE الإدخالات المكررة في عمود
- تحسّن فهارس الأعمدة المتعددة الاستعلامات التي ترشح تلك الأعمدة بترتيب معين
- لا تفهرس بشكل مفرط! قَيِّم احتياجات الاستعلام واحذف الفهارس غير المستخدمة
الاستفادة الكاملة من الفهارس أمر حاسم للأداء الأمثل لقاعدة بيانات MySQL، وخاصةً مع نمو البيانات. خذ الوقت لفهم التنازلات المتعلقة بالفهرسة وأفضل الممارسات عند تصميم مخطط قاعدة البيانات والاستعلامات الخاصة بك.