MySQL: مقدمة إلى استعلامات MySQL وخطة التنفيذ EXPLAIN

آخر تحديث: 2026-08-26

لا يمكنك كتابة استعلامات عالية الأداء حقًّا إلا إذا فهمت الميزات المتقدمة للفهارس.

يقدم هذا الدرس شرحًا متعمقًا لأنواع الفهارس وتحليل EXPLAIN.

1. ما ستتعلمه



2. الفهارس المجمعة والفهارس غير المجمعة

البعد الفهرس المجمَّع الفهرس غير المجمَّع
طريقة التخزين يتم تخزين البيانات والفهارس معًا تشير الفهارس إلى عناوين البيانات
الكمية يُسمح بواحد فقط يُسمح بعدة قطع
المفتاح الأساسي يستخدم InnoDB المفتاح الأساسي تلقائيًا الفهرس الثانوي
الاستعلام استرجاع البيانات مباشرة يتطلب البحث في الجدول

(1) البحث في جدول

100%
graph LR
    A[Secondary Index<br/>idx_email] -->|Primary Key Value| B[Clustered Index<br/>PRIMARY]
    B -->|Complete Data| C[Data Row]
SQL
-- The process of table lookup
SELECT * FROM users WHERE email = 'alice@email.com';
-- 1. Find id=1 in idx_email
-- 2. Find complete data for id=1 in PRIMARY


3. مؤشرات التغطية

جميع الحقول الموجودة في الاستعلام مدرجة في الفهرس، لذا لا داعي للرجوع إلى الجدول.

▶ مثال: مؤشر التراكب

SQL
-- Create a composite index
CREATE INDEX idx_name_email ON users(username, email);

-- Covering Index(No need to return to the table)
SELECT username, email FROM users WHERE username = 'alice';

-- Non-covering index(Need to return to the table)
SELECT * FROM users WHERE username = 'alice';
▶ جرّب الكود
النوع العودة إلى الجدول الأداء
فهرس التغطية رقم سريع
فهرس غير شامل نعم بطيء


4. المؤشرات المركبة والبادئة الموجودة في أقصى اليسار

(1) مبدأ البادئة الموجودة في أقصى اليسار

يمكن استخدام المؤشر المركب (a, b, c) في الاستعلامات التالية:

SQL
WHERE a = 1                    -- ✅ Using index
WHERE a = 1 AND b = 2         -- ✅ Using index
WHERE a = 1 AND b = 2 AND c = 3  -- ✅ Using index
WHERE b = 2                    -- ❌ Index not used
WHERE b = 2 AND c = 3         -- ❌ Index not used

▶ مثال: التحقق من استخدام الفهرس

SQL
CREATE INDEX idx_abc ON orders(customer_id, status, order_date);

-- ✅ Using index
EXPLAIN SELECT * FROM orders WHERE customer_id = 1;
EXPLAIN SELECT * FROM orders WHERE customer_id = 1 AND status = 'paid';
EXPLAIN SELECT * FROM orders WHERE customer_id = 1 AND status = 'paid' AND order_date > '2026-01-01';

-- ❌ Index not used (Violates the Leftmost Prefix Rule)
EXPLAIN SELECT * FROM orders WHERE status = 'paid';
▶ جرّب الكود

5. الحالات التي تصبح فيها الفهارس غير فعالة

السيناريو المثال السبب
عمليات الدوال WHERE YEAR(date) = 2026 الفهرس المحاط بدالة
التحويل الضمني WHERE phone = 13800001111 الاستعلام عن مصفوفات السلاسل باستخدام الأرقام
LIKE Left Fuzzy WHERE name LIKE '%john' البادئة غير مؤكدة
شرط OR WHERE a = 1 OR b = 2 بعض الحقول غير مفهرسة
غير موجود/غير موجود WHERE id NOT IN (1,2) يختار المُحسِّن إجراء مسح كامل للجدول
IS NULL/IS NOT NULL WHERE col IS NULL يعتمد على نسبة القيم NULL

▶ مثال: فشل الفهرس والاستعادة

SQL
-- ❌ Index Invalidation
SELECT * FROM users WHERE YEAR(created_at) = 2026;

-- ✅ Fix: Change to a range query
SELECT * FROM users WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01';

-- ❌ Index Invalidation
SELECT * FROM users WHERE phone = 13800001111;

-- ✅ Fix: Use quotes
SELECT * FROM users WHERE phone = '13800001111';
▶ جرّب الكود

6. شرح خطة التنفيذ

▶ مثال: استخدام EXPLAIN

SQL
EXPLAIN SELECT * FROM users WHERE email = 'alice@email.com';
▶ جرّب الكود

الناتج:

TEXT 📖 للعرض فقط
+----+-------+------+---------+------+----------+-------+
| id | type  | key  | key_len | ref  | rows     | Extra |
+----+-------+------+---------+------+----------+-------+
|  1 | const | idx_email | 402 | const | 1 |       |
+----+-------+------+---------+------+----------+-------+

(1) وصف الحقول الرئيسية

الحقل الوصف القيم الصالحة
النوع نوع الوصول const > eq_ref > ref > range > index > ALL
المفتاح الفهرس المستخدم غير NULL
الصفوف العدد التقديري للصفوف المطلوب مسحها كلما كان الرقم أقل، كان ذلك أفضل
إضافي معلومات إضافية استخدام الفهرس (الفهرس الشامل)

(2) نوع الوصول

النوع الوصف الإيجابيات والسلبيات
ثابت استعلامات المساواة للمفتاح الأساسي/الفهرس الفريد ⭐⭐⭐
eq_ref استخدام المفتاح الأساسي/الفهرس الفريد في عمليات الربط ⭐⭐⭐
المرجع استعلامات المساواة على الفهارس غير الفريدة ⭐⭐
النطاق استعلام نطاق الفهرس ⭐⭐
الفهرس المسح الكامل للفهرس
الكل مسح كامل للجدول


❓ أسئلة شائعة

س كيف يجب أن أختار ترتيب الحقول في الفهرس المركب؟
ج ضع الحقول ذات الانتقائية العالية أولاً، وكذلك الحقول التي يتم الاستعلام عنها بشكل متكرر أولاً.
س هل قيم «rows» في EXPLAIN دقيقة؟
ج إنها تقديرات وليست قيمًا دقيقة. ومع ذلك، يمكن استخدامها لتقييم كفاءة الاستعلام.
س ماذا عليّ أن أفعل إذا أصبح الفهرس غير فعال؟
ج أعد كتابة جملة SQL لتجنب الحالات التي يصبح فيها الفهرس غير فعال، أو أنشئ فهرسًا وظيفيًّا (MySQL 8.0 وما بعده).
س هل قيم «rows» في EXPLAIN دقيقة؟
ج إنها تقديرات وليست قيمًا دقيقة، لكن يمكنك تقييم فعالية عمليات التحسين من خلال مقارنة التغيرات النسبية. استخدم الأمر ANALYZE TABLE لتحديث الإحصائيات.
س متى ينبغي استخدام فهرس البادئة؟
ج عندما يكون حقل VARCHAR طويلاً جدًّا وتكون البادئة مميزة بدرجة كافية. على سبيل المثال، INDEX(email(10)) — شريطة أن تبلغ درجة تمييز الأحرف العشرة الأولى أكثر من 95%.

📖 ملخص


📝 تمارين

  1. سؤال أساسي (مستوى الصعوبة: ⭐): استخدم EXPLAIN لتحليل استعلام ما وتحديد ما إذا كان يتم استخدام فهرس أم لا.

  2. مشكلة متقدمة (درجة الصعوبة ⭐⭐): أنشئ فهرسًا مركبًا للتحقق من مبدأ البادئة الموجودة في أقصى اليسار.

  3. سؤال التحدي (مستوى الصعوبة: ⭐⭐⭐): حدد ثلاثة سيناريوهات تكون فيها الفهارس غير فعالة واقترح حلولاً لها.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%