قاعدة البيانات هي القلب الذي ينبض في كل تحميل صفحة على موقع ووردبريس؛ فكل زيارة تُطلق عشرات الاستعلامات لجلب المنشورات والإعدادات والقوائم. مع الوقت تتضخّم القاعدة بمراجعات لا حصر لها، وtransients منتهية الصلاحية، وتعليقات سبام، وجداول يتيمة خلّفتها إضافات محذوفة — فيرتفع زمن الاستجابة الأول (TTFB) ويتباطأ الموقع. الحلّ ليس واحدًا بل طبقات: تنظيف آمن (بعد نسخة احتياطية دائمًا)، وإضافة فهارس (Indexes) للاستعلامات المتكرّرة، وتشغيل OPTIMIZE TABLE لاستعادة المساحة، واستخدام كاش الكائنات عبر Redis لتقليل ضرب القاعدة، ورصد الاستعلامات البطيئة وضبطها. في هذا الدليل أوامر SQL وWP-CLI جاهزة وجداول مرجعية لكل خطوة.
قبل أي شيء، ضع هذه القاعدة الذهبية نصب عينيك: لا تحذف صفًّا واحدًا من قاعدة البيانات قبل أخذ نسخة احتياطية كاملة قابلة للاستعادة. خطأ واحد في عبارة DELETE بلا شرط WHERE صحيح قد يمحو محتوى سنوات في ثوانٍ. القاعدة ليست ملفًا تتلاعب به بحرية، بل هي موقعك كلّه. وللاطّلاع على الصورة الأشمل لتسريع موقعك راجع الدليل الشامل لتسريع موقعك، فتحسين القاعدة جزء من منظومة أكبر لا حلٌّ سحري منفرد.
لماذا تبطئ قاعدة البيانات موقعك أصلًا؟
كل صفحة في ووردبريس ليست ملفًا جاهزًا على القرص يُسلَّم كما هو؛ بل تُبنى ديناميكيًا في كل زيارة. عند طلب صفحة، يشغّل ووردبريس شيفرة PHP تطلق سلسلة استعلامات SQL: من أنت؟ ما إعدادات الموقع؟ ما القائمة؟ ما المنشور المطلوب؟ ما تعليقاته؟ ما الإضافات المفعّلة وإعداداتها؟ صفحة بسيطة قد تطلق 20–40 استعلامًا، وصفحة متجر WooCommerce ثقيلة قد تتجاوز 200 استعلام. كل استعلام يحتاج وقتًا للوصول للقرص ومعالجة النتيجة وإعادتها.
هنا تظهر المشكلة: حين تكون القاعدة نظيفة وصغيرة ومفهرسة جيدًا، تنتهي هذه الاستعلامات في أجزاء من الألف من الثانية. لكن حين تتضخّم — جدول wp_options فيه عشرات آلاف الصفوف، وwp_posts فيه مراجعات أكثر من المنشورات الحقيقية، وwp_postmeta منتفخ بسجلّات إضافات محذوفة — يصبح كل استعلام أبطأ، ويتراكم البطء فيرتفع TTFB. والنتيجة المباشرة: تأخّر ظهور المحتوى، تدهور مؤشّر LCP، وارتفاع معدّل الارتداد.
العلاقة بين القاعدة والسرعة ليست خطية بسيطة، بل تتفاقم. استعلام يأخذ 5 ملي ثانية في القاعدة النظيفة قد يأخذ 200 ملي ثانية في قاعدة متضخّمة بلا فهارس، وإذا تكرّر ذلك في 30 استعلامًا لكل صفحة، فالفرق بين موقع يستجيب في 300 ملي ثانية وآخر يتعثّر عند 4 ثوانٍ. لفهم كيف يندرج هذا ضمن طبقات الأداء المختلفة، اطّلع على أنواع الكاش ومتى تستخدم كلًا.
| المرحلة | حالة القاعدة | متوسّط زمن الاستعلام | أثر على TTFB |
|---|---|---|---|
| موقع جديد | نظيفة، صغيرة، مفهرسة | 1–5 ملي ثانية | منخفض جدًا |
| بعد سنة استخدام | بعض التضخّم، autoload متوسط | 10–30 ملي ثانية | ملحوظ |
| بعد سنوات + إضافات كثيرة | متضخّمة، جداول يتيمة، بلا فهارس | 50–300 ملي ثانية | عالٍ جدًا |
| متجر WooCommerce نشط بلا صيانة | postmeta منتفخ، transients متراكمة | 100–500 ملي ثانية | حرج |
مصادر التضخّم: من أين يأتي الانتفاخ؟
قبل أن تنظّف، افهم ما الذي تنظّفه. تضخّم القاعدة ليس سحرًا بل نتيجة سلوكيات افتراضية في ووردبريس وإضافاته تتراكم بصمت. الجدول التالي يلخّص أبرز مصادر التضخّم وأين تسكن:
| المصدر | الجدول | لماذا يتراكم | خطورته |
|---|---|---|---|
| المراجعات (Revisions) | wp_posts | يحفظ ووردبريس نسخة عند كل تعديل بلا حدّ افتراضي | عالية |
| المسوّدات التلقائية (Auto-drafts) | wp_posts | حفظ تلقائي كل 60 ثانية أثناء الكتابة | متوسطة |
| transients منتهية | wp_options | بيانات مؤقتة لا تُحذف دائمًا بعد انتهائها | عالية |
| تعليقات السبام والمهملات | wp_comments | تتراكم إن لم تُفرّغ يدويًا | متوسطة |
| الجداول اليتيمة (Orphaned) | جداول مستقلة | إضافات محذوفة لم تنظّف بياناتها | متوسطة |
| postmeta يتيم | wp_postmeta | بيانات وصفية لمنشورات/مراجعات محذوفة | عالية |
| pingbacks وtrackbacks | wp_comments | إشعارات روابط قديمة | منخفضة |
| overhead (تجزئة) | كل الجداول | مساحة محرّرة لم تُستردّ بعد الحذف | متوسطة |
المراجعات والمسوّدات التلقائية
عند كل ضغطة "تحديث" لمقال، يخزّن ووردبريس النسخة السابقة كـ"مراجعة" في جدول wp_posts. هذه ميزة رائعة للتراجع، لكن بلا حدّ أقصى افتراضي يمكن أن يتراكم لمقال واحد 50 مراجعة أو أكثر. مع مئات المقالات، تصبح المراجعات أضعاف عدد المنشورات الحقيقية، وكلها تُحمَّل وتُفهرَس مع المحتوى الفعلي.
transients المنتهية
الـtransients آلية تخزين مؤقت داخل القاعدة (في wp_options افتراضيًا). تستخدمها الإضافات لحفظ نتائج عمليات مكلفة (مثل استعلام API خارجي) لفترة محدّدة. المشكلة أنّ ووردبريس لا يحذف الـtransient المنتهي فورًا، بل عند طلبه فقط؛ فالـtransients التي لم يعد أحد يطلبها تبقى في القاعدة إلى الأبد. في المواقع القديمة قد تشكّل آلاف الصفوف في wp_options، وأخطرها ما كان منها autoload = yes.
الجداول اليتيمة و postmeta اليتيم
كثير من الإضافات تنشئ جداول خاصة بها (wp_redirection_logs، wp_yoast_indexable، إلخ). عند حذف الإضافة من لوحة التحكم، غالبًا لا تُحذف جداولها وبياناتها، فتبقى "يتيمة" تشغل مساحة وتُدرَج في أي نسخة احتياطية. كذلك حين تُحذف منشورات أو مراجعات، قد تبقى صفوفها الوصفية في wp_postmeta بلا منشور أب — وهذا من أكثر مصادر الانتفاخ الصامتة.
تشريح قاعدة بيانات تطبيق ويب: أين يتراكم الوزن
قبل أي تنظيف تحتاج خريطة. أيًّا كان التطبيق الذي يشغّل موقعك، تتوزّع جداوله على أربع عائلات لكلٍّ منها سلوك نموّ مختلف تمامًا — ومعرفة العائلة تخبرك مقدّمًا أين ستجد الانتفاخ:
| العائلة | ما تخزّنه | سلوك النموّ | خطر التضخّم |
|---|---|---|---|
| المحتوى الأساسي | المنشورات، المنتجات، الصفحات، المستخدمون | ينمو بمعدّل عملك | منخفض — هذا نموّ صحّي |
| البيانات الوصفية | حقول مخصّصة مرتبطة بكل عنصر | مضاعَف: عشرات الصفوف لكل عنصر واحد | مرتفع جدًّا |
| الجلسات والمؤقّتات | سلال، جلسات زوّار، كاش، رموز مؤقّتة | ينمو بعدد الزيارات لا بالمحتوى | مرتفع، وينفجر فجأة |
| السجلّات والطوابير | سجلّ الأحداث، المهامّ المجدولة، محاولات الإرسال | يكتب باستمرار ولا يحذف أبدًا | الأخطر — بلا سقف |
أخطرها العائلتان الأخيرتان لأنّ نموّهما لا علاقة له بحجم موقعك. موقع صغير بمئة صفحة قد يحمل جدول جلسات فيه مئات آلاف الصفوف لأنّ كل زائر عابر ترك أثرًا لم يُنظَّف. وجدول طابور المهامّ في تطبيق مهمَل قد يتجاوز المليون صفّ خلال شهور، فتصبح كل قراءة منه عملية مسح كاملة.
أمّا البيانات الوصفية فتستحقّ انتباهًا خاصًّا لأنّ بنيتها مضاعِفة بطبعها: كل عنصر محتوى واحد قد يجرّ خلفه عشرين أو ثلاثين صفًّا في جدول منفصل. والأسوأ أنّ حذف العنصر الأصلي لا يحذفها دائمًا، فتبقى صفوفًا يتيمة تشير إلى شيء لم يعد موجودًا: تشغل مساحة، تبطئ الفهارس، ولا تُقرأ أبدًا.
ابدأ تشخيصك دائمًا بترتيب الجداول تنازليًّا حسب عدد الصفوف والحجم، لا بالتخمين:
SELECT table_name,
table_rows,
ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = DATABASE()
ORDER BY (data_length + index_length) DESC
LIMIT 15;
الجدول الأوّل في هذه القائمة هو حيث تبدأ، مهما بدا لك المنطق يقول غير ذلك.
ملاحظة نطاق: إن كان موقعك على ووردبريس تحديدًا، فأسماء الجداول وأدواتها مشروحة بالتفصيل في تنظيف وتحسين قاعدة بيانات ووردبريس — وهو المكان الصحيح لتبدأ منه.
الاستعلام الذي يعمل في كل طلب
أخطر استعلام في تطبيقك ليس الأبطأ، بل الذي يعمل في كل طلب. استعلام يستغرق 5 مللي ثانية ويُنفَّذ مرّة في اليوم لا يعنيك؛ واستعلام يستغرق 5 مللي ثانية ويُنفَّذ عشر مرّات في كل تحميل صفحة يبتلع نصف ميزانية استجابتك.
أغلب أطر العمل تحمّل عند بدء كل طلب كتلة إعدادات «تمهيدية» قبل أن تعرف أصلًا ماذا ستعرض. هذه الكتلة مصمّمة لتكون صغيرة، لكنها تتضخّم بصمت حين تخزّن فيها الإضافات بيانات لا تخصّها: سجلّات، نتائج مكاشة، مصفوفات إعدادات ضخمة. النتيجة أنّ كل زائر — حتى من يقرأ صفحة ثابتة — يدفع ثمن جلب وفكّ ميغابايتات لا تُستخدم.
ثلاثة أنماط تكلّفك في كل طلب:
- التحميل التمهيدي المنتفخ — كتلة الإعدادات التي تُقرأ دائمًا. القاعدة العملية: أبقِها تحت ميغابايت واحد. تجاوزُها ثلاثة ميغابايت حالة حرجة تُعالَج فورًا.
- مشكلة N+1 — استعلام واحد يجلب قائمة، ثمّ استعلام منفصل لكل عنصر فيها. صفحة تعرض 50 منتجًا قد تُطلق 51 استعلامًا بدل اثنين. علاجها في الكود لا في القاعدة: اجلب الدفعة كاملة مرّة واحدة.
SELECT *على صفوف عريضة — تجلب أعمدة نصّية ضخمة لا يعرضها أحد. اطلب الأعمدة التي تحتاجها فقط.
لقياس هذا بصدق لا تعتمد على انطباعك: فعّل عدّاد الاستعلامات في بيئة التطوير وانظر إلى عدد الاستعلامات لكل صفحة لا إلى زمنها الإجمالي. صفحة صحّية تحت 50 استعلامًا؛ وما تجاوز 200 يستدعي وقوفًا فوريًّا. ثمّ راجع زمن أوّل بايت لتفهم أين يقع هذا كلّه من تجربة الزائر.
التنظيف الآمن: النسخة الاحتياطية أولًا
قبل تشغيل أي عبارة DELETE أو UPDATE، خذ نسخة احتياطية كاملة. هذه ليست توصية بل شرط لا يُتجاوز. النسخة تتيح لك الرجوع لحظة وقوع أي خطأ. للتعمّق في استراتيجية النسخ راجع دليلنا المخصّص لذلك، أمّا الأمر السريع عبر سطر الأوامر فهو:
# نسخة احتياطية كاملة لقاعدة البيانات قبل أي تنظيف
mysqldump -u DB_USER -p DB_NAME > backup_$(date +%F).sql
# للملفات الكبيرة: ضغط فوري لتوفير المساحة
mysqldump -u DB_USER -p DB_NAME | gzip > backup_$(date +%F).sql.gz
# عبر WP-CLI (يأخذ بيانات الاتصال من wp-config تلقائيًا)
wp db export backup_$(date +%F).sql
وللاستعادة عند الحاجة:
# استعادة من النسخة (انتبه: يستبدل القاعدة الحالية)
wp db import backup_2026-06-13.sql
اختبر دائمًا أنّ النسخة قابلة للاستعادة فعلًا على بيئة تجريبية (staging) قبل أن تعتمد عليها. نسخة لم تُختبر استعادتها = لا نسخة.
التنظيف اليدوي بـ SQL
بعد النسخة، يمكنك التنظيف بأوامر SQL مباشرة عبر phpMyAdmin أو سطر الأوامر. ابدأ بالمراجعات:
-- حذف كل المراجعات (Revisions)
DELETE FROM wp_posts WHERE post_type = 'revision';
-- حذف المسوّدات التلقائية (Auto-drafts)
DELETE FROM wp_posts WHERE post_status = 'auto-draft';
-- حذف عناصر سلّة المهملات
DELETE FROM wp_posts WHERE post_status = 'trash';
ثم نظّف الـtransients المنتهية. الـtransients تظهر في wp_options بأسماء تبدأ بـ_transient_ و_transient_timeout_ (والنسخة الموقعية _site_transient_):
-- حذف كل الـtransients (آمن: ووردبريس يعيد بناء ما يحتاجه)
DELETE FROM wp_options WHERE option_name LIKE '\_transient\_%';
DELETE FROM wp_options WHERE option_name LIKE '\_site\_transient\_%';
نظّف بعد ذلك تعليقات السبام والمهملات والـpingbacks:
-- حذف تعليقات السبام والمهملات
DELETE FROM wp_comments WHERE comment_approved = 'spam';
DELETE FROM wp_comments WHERE comment_approved = 'trash';
-- حذف pingbacks و trackbacks
DELETE FROM wp_comments WHERE comment_type IN ('pingback', 'trackback');
أخيرًا، نظّف البيانات الوصفية اليتيمة — وهذا من أهمّ ما يقلّص حجم wp_postmeta وwp_commentmeta:
-- حذف postmeta لمنشورات لم تعد موجودة (يتيم)
DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
-- حذف commentmeta لتعليقات لم تعد موجودة
DELETE cm FROM wp_commentmeta cm
LEFT JOIN wp_comments c ON c.comment_ID = cm.comment_id
WHERE c.comment_ID IS NULL;
-- حذف علاقات المصطلحات اليتيمة
DELETE tr FROM wp_term_relationships tr
LEFT JOIN wp_posts p ON p.ID = tr.object_id
WHERE p.ID IS NULL;
جاهز لإطلاق موقعك على استضافة سريعة؟
خطط استضافة wpressly على أقراص NVMe مع SSL مجاني ودعم عربي — اختر الخطة المناسبة لحجمك وانطلق اليوم.
اكتشف خطط الاستضافةالتنظيف بـ WP-CLI (الأسرع والأكثر أمانًا)
إن كانت لديك صلاحية SSH، فإنّ WP-CLI أسرع وأقل عرضة للخطأ من SQL اليدوي، لأنه يتعامل مع منطق ووردبريس لا مع الصفوف الخام. أوامر التنظيف الأساسية:
# حذف كل الـtransients (المنتهية وغيرها)
wp transient delete --all
# حذف الـtransients المنتهية فقط (أكثر تحفّظًا)
wp transient delete --expired
# تشغيل تحسين كامل للقاعدة (يكافئ OPTIMIZE TABLE لكل الجداول)
wp db optimize
# حذف المراجعات عبر إضافة wp-cli (مثال بإضافة معروفة)
wp post delete $(wp post list --post_type='revision' --format=ids) --force
ميزة WP-CLI أنّه يحترم الـhooks والمنطق الداخلي، فلا يترك بيانات وصفية يتيمة كما قد يحدث مع DELETE المباشر على wp_posts وحده.
التنظيف بالإضافات
إن لم تكن مرتاحًا مع SQL أو سطر الأوامر، فإضافات التنظيف توفّر واجهة رسومية آمنة نسبيًا. الجدول يقارن أشهرها:
| الإضافة | تنظيف المراجعات | transients | OPTIMIZE | جدولة تلقائية | ملاحظة |
|---|---|---|---|---|---|
| WP-Optimize | نعم | نعم | نعم | نعم | شامل + كاش صفحات |
| Advanced Database Cleaner | نعم | نعم | نعم | نعم | يكتشف الجداول اليتيمة جيدًا |
| WP-Sweep | نعم | نعم | نعم | لا | يستخدم دوال ووردبريس (آمن) |
| Perfmatters | جزئي | نعم | لا | نعم | يركّز على تقليل autoload |
نصيحة: حتى مع الإضافات، خذ نسخة احتياطية قبل أوّل عملية تنظيف، وراجع تقرير ما سيُحذف قبل التأكيد. وبعد انتهاء التنظيف، يُفضَّل تعطيل إضافة التنظيف وعدم تركها مفعّلة دائمًا — فعّلها للصيانة الدورية فقط لتقليل الحمل.
الفهارس (Indexes): تسريع البحث في القاعدة
تخيّل كتابًا بلا فهرس: للعثور على كلمة تقلّب كل الصفحات. الفهرس في قاعدة البيانات يعمل تمامًا كفهرس الكتاب — يتيح لمحرّك القاعدة القفز مباشرة إلى الصفوف المطلوبة بدل مسح الجدول كاملًا (Full Table Scan). على الجداول الكبيرة، الفرق بين استعلام مفهرس وآخر غير مفهرس قد يكون بين ملي ثانية وعدّة ثوانٍ.
ووردبريس يأتي بفهارس افتراضية جيدة على الجداول الأساسية. لكن المشكلة تظهر مع الاستعلامات على wp_postmeta وwp_options حين تبحث الإضافات بقيم meta_key/meta_value غير مفهرسة. أنواع الفهارس الشائعة:
| نوع الفهرس | يستخدم لـ | مثال |
|---|---|---|
| PRIMARY KEY | المعرّف الفريد للصف | ID في wp_posts |
| UNIQUE | منع تكرار القيمة | بريد المستخدم |
| INDEX (عادي) | تسريع البحث/الترتيب | meta_key في wp_postmeta |
| COMPOSITE | بحث بأكثر من عمود معًا | (post_id, meta_key) |
| FULLTEXT | البحث النصّي | محتوى المنشورات |
متى تضيف فهرسًا؟ حين ترصد استعلامًا بطيئًا يبحث بعمود غير مفهرس ويتكرّر كثيرًا. مثال شائع: إضافة تبحث في wp_postmeta بـmeta_key معيّن على جدول ضخم:
-- فحص استعلام لمعرفة هل يستخدم فهرسًا (ابحث عن type=ALL = مسح كامل)
EXPLAIN SELECT * FROM wp_postmeta WHERE meta_key = 'my_custom_field';
-- إضافة فهرس على meta_key لتسريع بحث الإضافات
ALTER TABLE wp_postmeta ADD INDEX idx_meta_key (meta_key(191));
-- فهرس مركّب لاستعلامات تجمع post_id مع meta_key
ALTER TABLE wp_postmeta
ADD INDEX idx_post_meta (post_id, meta_key(191));
ملاحظة تقنية مهمّة: نستخدم meta_key(191) (فهرس على أول 191 حرفًا) لأنّ ترميز utf8mb4 يحدّ طول مفتاح الفهرس. لا تفرط في إضافة الفهارس: كل فهرس يسرّع القراءة لكنه يبطئ الكتابة ويزيد الحجم. أضِف فهرسًا فقط حين تثبت حاجته بقياس فعلي عبر EXPLAIN.
OPTIMIZE TABLE وإلغاء التجزئة
حين تحذف صفوفًا كثيرة، لا تُستردّ المساحة تلقائيًا؛ تبقى "ثقوب" داخل ملفات الجدول تُسمّى overhead أو تجزئة (fragmentation). الأمر OPTIMIZE TABLE يعيد بناء الجدول فيستردّ المساحة ويعيد ترتيب الفهارس ويحسّن أداء القراءة:
-- فحص حجم الجداول والـ overhead (التجزئة) بالميجابايت
SELECT table_name AS الجدول,
ROUND(data_length/1024/1024, 2) AS بيانات_MB,
ROUND(index_length/1024/1024, 2) AS فهارس_MB,
ROUND(data_free/1024/1024, 2) AS مهدور_MB
FROM information_schema.TABLES
WHERE table_schema = DATABASE()
ORDER BY data_free DESC;
-- تحسين جدول محدّد
OPTIMIZE TABLE wp_postmeta;
-- تحسين أكثر من جدول معًا
OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options, wp_comments;
مهم: على جداول InnoDB (المحرّك الحديث) ينفّذ MySQL داخليًا عملية إعادة بناء كاملة قد تقفل الجدول لحظيًا، لذا شغّله في أوقات الازدحام المنخفض. وعبر WP-CLI يكفي wp db optimize لتحسين كل الجداول دفعة واحدة. لا حاجة لتشغيل OPTIMIZE يوميًا — مرّة شهريًا أو بعد حذف كبير يكفي.
محرّك InnoDB مقابل MyISAM
محرّك التخزين هو الآلية التي تخزّن بها القاعدة بياناتها وتديرها. ووردبريس الحديث يستخدم InnoDB افتراضيًا، لكن مواقع قديمة قد تحتوي جداول عالقة على MyISAM الأقدم. الفرق جوهري للأداء والموثوقية:
| المعيار | InnoDB | MyISAM |
|---|---|---|
| القفل | على مستوى الصف (Row-level) | على مستوى الجدول (Table-level) |
| المعاملات (Transactions) | مدعومة | غير مدعومة |
| الاسترداد بعد العطل | ممتاز (Crash-safe) | ضعيف، عرضة للتلف |
| الأداء مع الكتابة المتزامنة | عالٍ | منخفض (قفل الجدول كاملًا) |
| المفاتيح الأجنبية | مدعومة | غير مدعومة |
| الأنسب لـ | ووردبريس الحديث، المتاجر | أرشيف قراءة فقط (نادرًا) |
قفل الصف في InnoDB هو الفارق الحاسم: في MyISAM، أي كتابة تقفل الجدول كلّه فتنتظر بقية الطلبات؛ أمّا InnoDB فيقفل الصف المعنيّ فقط، ما يسمح بكتابات متزامنة — حيوي للمواقع النشطة والمتاجر. لفحص محرّك جداولك وتحويل أي جدول قديم:
-- فحص محرّك التخزين لكل جدول
SELECT table_name, engine
FROM information_schema.TABLES
WHERE table_schema = DATABASE();
-- تحويل جدول من MyISAM إلى InnoDB (بعد نسخة احتياطية)
ALTER TABLE wp_comments ENGINE = InnoDB;
قبل التحويل تأكّد أنّ نسخة MySQL/MariaDB لديك تدعم InnoDB (وهو الافتراضي منذ سنوات)، وأنّ الجدول لا يعتمد على فهارس FULLTEXT خاصة بـMyISAM لم تكن مدعومة في إصدارات قديمة جدًا من InnoDB.
كاش الكائنات (Object Cache) بـ Redis لتقليل ضرب القاعدة
أقوى ترقية أداء بعد التنظيف هي كاش الكائنات الدائم (Persistent Object Cache). افتراضيًا، يخزّن ووردبريس نتائج الاستعلامات في الذاكرة لمدّة الطلب الواحد فقط؛ فبمجرّد انتهاء تحميل الصفحة، تُنسى. الطلب التالي يكرّر نفس الاستعلامات من الصفر. كاش الكائنات الدائم (عبر Redis أو Memcached) يحفظ هذه النتائج في ذاكرة سريعة بين الطلبات، فلا تضرب القاعدة مرارًا بنفس السؤال.
الفرق هائل في لوحة الإدارة والمتاجر والصفحات الديناميكية التي لا يفيدها كاش الصفحات الكامل. لفهم كيف يندرج كاش الكائنات ضمن طبقات الكاش المختلفة (المتصفّح، الصفحة، الكائنات، Opcode) راجع أنواع الكاش ومتى تستخدم كلًا. تفعيل Redis يتمّ عادة بإضافة مثل Redis Object Cache بعد تثبيت خادم Redis، ثم تفعيله في wp-config.php:
// في wp-config.php — إعداد اتصال Redis
define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
define( 'WP_REDIS_DATABASE', 0 );
// مهلة الاتصال (ثوانٍ) لتجنّب التعليق لو توقّف Redis
define( 'WP_REDIS_TIMEOUT', 1 );
define( 'WP_REDIS_READ_TIMEOUT', 1 );
// بادئة مفاتيح فريدة (مفيد عند مشاركة Redis بين مواقع)
define( 'WP_CACHE_KEY_SALT', 'mysite_' );
| الطبقة | يخزّن | يقلّل ضرب القاعدة؟ | الأنسب لـ |
|---|---|---|---|
| كاش الصفحة | HTML كامل | نعم (للزوّار) | المحتوى الثابت |
| كاش الكائنات (Redis) | نتائج الاستعلامات | نعم (لوحة + ديناميكي) | المتاجر والمواقع النشطة |
| كاش Opcode (OPcache) | شيفرة PHP المُجمَّعة | لا (يسرّع PHP) | كل المواقع |
ملاحظة: يحتاج Redis إلى خادم يدعمه (VPS أو استضافة مُدارة توفّره). كثير من خطط الاستضافة المشتركة الرخيصة لا توفّر Redis، وهذا أحد أسباب اختيار استضافة جادّة للمواقع النشطة.
جاهز لإطلاق موقعك على استضافة سريعة؟
خطط استضافة wpressly على أقراص NVMe مع SSL مجاني ودعم عربي — اختر الخطة المناسبة لحجمك وانطلق اليوم.
اكتشف خطط الاستضافةرصد الاستعلامات البطيئة وضبطها
لا تحسّن ما لا تقيس. قبل أن تضيف فهرسًا أو تعيد كتابة استعلام، يجب أن تعرف أيّ الاستعلامات بطيئة فعلًا. أداتان رئيسيتان: سجلّ الاستعلامات البطيئة على مستوى MySQL، وإضافة Query Monitor على مستوى ووردبريس.
تفعيل سجلّ الاستعلامات البطيئة (Slow Query Log)
سجلّ الاستعلامات البطيئة يسجّل كل استعلام يتجاوز زمنًا تحدّده. يمكن تفعيله مؤقتًا دون إعادة تشغيل الخادم:
-- تفعيل سجلّ الاستعلامات البطيئة (مؤقت حتى إعادة التشغيل)
SET GLOBAL slow_query_log = 'ON';
-- تسجيل أي استعلام يتجاوز ثانيتين
SET GLOBAL long_query_time = 2;
-- مسار ملف السجلّ
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
-- تسجيل الاستعلامات التي لا تستخدم فهرسًا (مفيد للتشخيص)
SET GLOBAL log_queries_not_using_indexes = 'ON';
لتفعيله دائمًا، أضِف ما يلي في ملف إعداد MySQL (my.cnf أو mysqld.cnf):
# في قسم [mysqld] من my.cnf
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = 1
ثم استخدم أداة مثل mysqldumpslow لتلخيص أكثر الاستعلامات بطئًا وتكرارًا:
# تلخيص أبطأ 10 استعلامات حسب متوسّط الزمن
mysqldumpslow -s at -t 10 /var/log/mysql/slow.log
Query Monitor داخل ووردبريس
إضافة Query Monitor المجانية تعرض — لكل صفحة تزورها وأنت مسجّل دخول كمدير — كل الاستعلامات وزمنها والإضافة المسؤولة عنها والاستعلامات المكرّرة. هذا أسرع طريقة لربط الاستعلام البطيء بمصدره: قد تكتشف أنّ إضافة واحدة مسؤولة عن نصف زمن القاعدة، فتستبدلها أو تعطّلها.
| الأداة | المستوى | يكشف | الأنسب لـ |
|---|---|---|---|
| Slow Query Log | MySQL | الاستعلامات البطيئة عبر الموقع كله | تشخيص الخادم |
| Query Monitor | ووردبريس | استعلامات الصفحة + مصدرها | ربط الاستعلام بالإضافة |
| EXPLAIN | SQL | خطة تنفيذ استعلام واحد | تأكيد استخدام الفهرس |
| New Relic / APM | الخادم | الأداء عبر الزمن | المواقع الكبيرة |
اقطع التضخّم من التطبيق لا من القاعدة
التنظيف علاج يتكرّر كل شهر؛ والوقاية إعداد يُضبط مرّة. الفارق أنّ قاعدة البيانات لا تحذف شيئًا من تلقاء نفسها أبدًا — كل صفّ كُتب يبقى إلى أن يحذفه أحد صراحةً. لذلك أي بيانات يكتبها تطبيقك بلا سياسة عمر محدّدة ستنمو بلا سقف، والسؤال متى تصبح مشكلة لا هل.
أربع سياسات تحسم أغلب النموّ غير الصحّي:
| نوع البيانات | السياسة الصحيحة | الخطأ الشائع |
|---|---|---|
| نسخ المحتوى ومسوّداته | احتفظ بعدد محدود لكل عنصر | «احتفظ بكل شيء للأمان» |
| الجلسات والسلال المتروكة | احذف ما تجاوز 30–60 يومًا | لا سياسة إطلاقًا |
| المؤقّتات والكاش المخزَّن | احذف المنتهي دوريًّا | الاعتماد على أن التطبيق سينظّف |
| السجلّات وسجلّ الأحداث | احتفظ بنافذة زمنية ثمّ دوّرها | الاحتفاظ منذ أوّل يوم |
المفتاح أن تجعل الحذف مهمّة مجدولة تعمل وحدها، لا شيئًا تتذكّره. مهمّة أسبوعية تحذف الجلسات المنتهية والسجلّات القديمة تُبقي القاعدة عند حجم مستقرّ إلى الأبد — راجع دليل المهامّ المجدولة لإعدادها بشكل صحيح على الخادم.
وانتبه إلى ترتيب مهمّ: طبّق سياسة العمر قبل أن تحذف المتراكم. إن نظّفت مليون صفّ اليوم بلا سياسة، ستجدها عادت خلال شهور. وإن ضبطت السياسة أوّلًا، صار التنظيف الكبير عملية تفعلها مرّة واحدة لا دورة لا تنتهي.
الصيانة الدورية: جدول زمني عملي
تحسين القاعدة ليس حدثًا لمرّة واحدة بل عادة. الجدول التالي يقترح روتينًا واقعيًا حسب نوع الموقع:
| المهمّة | مدوّنة/موقع تعريفي | متجر WooCommerce نشط |
|---|---|---|
| نسخة احتياطية كاملة | يومية | كل 6 ساعات أو يومية |
| حذف المراجعات والمسوّدات | شهريًا | أسبوعيًا |
| حذف transients منتهية | شهريًا | أسبوعيًا |
| تفريغ سبام التعليقات | أسبوعيًا | أسبوعيًا |
OPTIMIZE TABLE / wp db optimize | شهريًا | شهريًا |
| فحص حجم autoload | كل 3 أشهر | شهريًا |
| مراجعة الجداول اليتيمة | بعد كل حذف إضافة | بعد كل حذف إضافة |
| مراجعة سجلّ الاستعلامات البطيئة | عند ملاحظة بطء | شهريًا |
يمكن أتمتة معظم هذه المهام عبر إضافة جدولة (WP-Optimize تدعم الجدولة) أو عبر cron job على الخادم يستدعي أوامر WP-CLI تلقائيًا. الأتمتة تضمن الاستمرارية بدل الاعتماد على التذكّر اليدوي.
أخطاء شائعة احذرها
كثير من المواقع تتضرّر من "تحسين" خاطئ أكثر مما تتضرّر من الإهمال. تجنّب هذه الأخطاء:
| الخطأ | لماذا خطير | الصواب |
|---|---|---|
| الحذف بلا نسخة احتياطية | خطأ واحد = فقدان دائم | نسخة كاملة مختبَرة أولًا |
DELETE بلا WHERE دقيق | يمسح أكثر مما تقصد | راجع العبارة، جرّبها على staging |
| تعطيل المراجعات تمامًا | تفقد القدرة على التراجع | حدّدها بـ 3–5 لا صفر |
| الإفراط في الفهارس | يبطئ الكتابة ويضخّم الحجم | فهرس بعد قياس EXPLAIN فقط |
| حذف جدول دون التأكّد | قد يكون مستخدمًا فعلًا | تحقّق من أنه يتيم حقًا |
| ترك إضافة تنظيف مفعّلة دائمًا | حمل دائم على الموقع | فعّلها للصيانة فقط |
OPTIMIZE في وقت الذروة | قد يقفل الجداول لحظيًا | شغّله في الازدحام المنخفض |
نصائح خبير لقاعدة بيانات صحّية
- افصل الـstaging عن الإنتاج: جرّب كل تنظيف أو تحويل محرّك على نسخة تجريبية أولًا، خصوصًا التحويلات بـ
ALTER TABLEعلى جداول ضخمة. - راقب الإضافات وقت التثبيت: بعض الإضافات تخزّن بيانات هائلة بـ
autoload = yes. افحص autoload بعد تثبيت أي إضافة جديدة ثقيلة. - نظّف عند حذف الإضافات: قبل حذف أي إضافة، ابحث هل توفّر خيار "حذف البيانات عند الإلغاء"، وإلا فستترك جداول وصفوفًا يتيمة.
- استخدم WP-CLI للأتمتة: أوامر مثل
wp transient delete --expiredوwp db optimizeمثالية لـcron jobs دورية بلا تدخّل. - لا تخلط الأسباب: غيّر شيئًا واحدًا وقِس أثره قبل الانتقال للتالي؛ تطبيق عشر تغييرات دفعة واحدة يخفي ما نفع وما ضرّ.
- القاعدة جزء من منظومة: قاعدة نظيفة لا تنفع وحدها إن كانت الاستضافة بطيئة أو الكاش معطّلًا. اقرأ تسريع موقع ووردبريس وفهم Core Web Vitals لرؤية الصورة كاملة.
تحسين قاعدة البيانات ليس مهمّة تقنية معزولة بل استثمار مباشر في سرعة موقعك وتجربة زوّاره وترتيبه في البحث. ابدأ بنسخة احتياطية، ثم نظّف الانتفاخ، أضِف الفهارس الضرورية، فعّل كاش الكائنات، وارصد الاستعلامات البطيئة — وحوّل الصيانة إلى عادة دورية لا حملة طارئة. واختر استضافة توفّر لك الأدوات التي يحتاجها هذا كله من SSH وRedis وموارد كافية.
جاهز لإطلاق موقعك على استضافة سريعة؟
خطط استضافة wpressly على أقراص NVMe مع SSL مجاني ودعم عربي — اختر الخطة المناسبة لحجمك وانطلق اليوم.
اكتشف خطط الاستضافةالأسئلة الشائعة
هل تحسين قاعدة البيانات يسرّع موقعي فعلًا؟ نعم، لكن بقدر مساهمة القاعدة في البطء لديك. إن كان TTFB مرتفعًا بسبب استعلامات بطيئة وautoload منتفخ وجداول متضخّمة، فالتنظيف والفهرسة وكاش الكائنات تُحدث فرقًا واضحًا. أمّا إن كان البطء من صور غير مضغوطة أو جافاسكربت ثقيل، فالقاعدة ليست العنق. لذا قِس أولًا أين يضيع الوقت.
كم مرّة يجب أن أنظّف قاعدة البيانات؟
للمدوّنات والمواقع التعريفية: تنظيف شامل شهريًا يكفي عادة. للمتاجر النشطة والمواقع كثيرة المحتوى: أسبوعيًا للمراجعات والـtransients، شهريًا لـOPTIMIZE. الأفضل أتمتة هذه المهام عبر جدولة أو cron بدل الاعتماد على التذكّر.
هل حذف المراجعات (Revisions) آمن؟
نعم، حذف المراجعات لا يؤثّر على المحتوى المنشور؛ المراجعة مجرّد نسخة سابقة محفوظة للتراجع. لكن خذ نسخة احتياطية أولًا كإجراء قياسي، وفكّر في الإبقاء على آخر 3–5 مراجعات لكل منشور بدل حذفها كلها، عبر ثابت WP_POST_REVISIONS.
ما الفرق بين OPTIMIZE TABLE وتنظيف الصفوف؟
تنظيف الصفوف (حذف المراجعات والـtransients) يقلّل عدد البيانات. أمّا OPTIMIZE TABLE فيعيد بناء الجدول ليستردّ المساحة المهدورة (overhead) الناتجة عن الحذف ويعيد ترتيب الفهارس. الترتيب الصحيح: نظّف الصفوف أولًا، ثم شغّل OPTIMIZE لاسترداد المساحة.
هل أحتاج Redis فعلًا لموقعي؟ يعتمد على نوع الموقع. المدوّنة الثابتة مع كاش صفحات جيّد قد لا تحتاجه كثيرًا. لكن المتاجر ومواقع العضوية والمنتديات — حيث المحتوى ديناميكي ولا يفيده كاش الصفحات الكامل — يستفيد كثيرًا من كاش الكائنات بـRedis لتقليل ضرب القاعدة. يحتاج Redis استضافة تدعمه (VPS أو مُدارة).
ما هو autoload ولماذا يهمّ؟
autoload عمود في جدول wp_options يحدّد هل يُحمَّل الخيار في ذاكرة كل تحميل صفحة. الإعدادات بـautoload = yes تُجلب جميعها في كل زيارة. إن خزّنت إضافة بيانات ضخمة بـautoload = yes، يتضخّم alloptions ويرتفع TTFB. الصحّي أن يبقى إجمالي autoload أقل من ميجابايت واحد.
هل يمكنني التحسين على استضافة مشتركة بلا SSH؟ نعم. تستطيع التنظيف عبر phpMyAdmin (من لوحة cPanel) بأوامر SQL، أو عبر إضافات مثل WP-Optimize من لوحة ووردبريس. لكن مزايا مثل سجلّ الاستعلامات البطيئة على مستوى الخادم وRedis غالبًا تحتاج VPS أو استضافة مُدارة توفّر هذه الإمكانات.
ماذا أفعل بالجداول اليتيمة من إضافات حذفتها؟
أولًا تأكّد تمامًا أنّ الجدول يتيم حقًا (يخصّ إضافة محذوفة ولا تستخدمه أي إضافة حالية). أدوات مثل Advanced Database Cleaner تكشفها وتساعدك على حذفها بأمان. خذ نسخة احتياطية، ثم احذف الجدول بـDROP TABLE بعد التأكّد. لا تتسرّع — بعض الجداول مشتركة بين إضافات.
هل إضافات التحسين تكفي أم أحتاج SQL يدويًا؟ لمعظم المستخدمين، إضافة موثوقة مثل WP-Optimize أو Advanced Database Cleaner تغطّي 90% من الحاجة بأمان وعبر واجهة رسومية. SQL اليدوي وWP-CLI يمنحان تحكّمًا أدقّ ومناسبان للمحترفين والحالات الخاصة (فهرس مخصّص، استعلام معيّن). الأهمّ في الحالتين: نسخة احتياطية قبل أي حذف.
هل التحسين قد يكسر موقعي؟
إن اتّبعت القواعد، الخطر ضئيل: نسخة احتياطية أولًا، وحذف ما تتأكّد منه فقط، وتجربة التحويلات الكبيرة على staging. المخاطر تأتي من العشوائية: DELETE بلا WHERE دقيق، أو حذف خيارات أساسية لووردبريس، أو حذف جدول مستخدم. التزم بالتنظيف الآمن الموصوف هنا وستكون بأمان.