Home Knowledge base Skyline Cloud أساسيات ضبط أداء قاعدة بيانات MySQL KNOWLEDGE BASE

أساسيات ضبط أداء قاعدة بيانات MySQL

دليل عملي خطوة بخطوة لضبط أداء MySQL 8.0 على خادم VPS أو خادم سحابي بنظام لينكس: القياس أولاً عبر سجل الاستعلامات البطيئة، وضبط حجم InnoDB buffer pool بشكل صحيح، وقراءة مخرجات EXPLAIN، وإضافة الفهارس المناسبة.

أساسيات ضبط أداء قاعدة بيانات MySQL

غالباً ما تكون قاعدة البيانات البطيئة هي السبب الأكثر شيوعاً وراء بطء التطبيق. وقبل أن ترفع مواصفات الخادم أو تعيد كتابة الشيفرة، فإن بضع ساعات من الضبط المنهجي لـ MySQL تستعيد عادةً معظم الأداء المفقود. يرشدك هذا الدليل عبر الأساسيات على خادم VPS أو خادم سحابي اعتيادي بنظام لينكس يشغّل MySQL 8.0: القياس، وضبط حجم الذاكرة، وقراءة خطط الاستعلام، وإضافة الفهارس المناسبة.

تنطبق هذه الخطوات على أي تثبيت قياسي لـ MySQL 8.0 — بما في ذلك قواعد البيانات المستضافة داخل المملكة على خادم VPS أو خادم سحابي من سكايلاين كلاود، حيث يساعد إبقاء بياناتك داخل المملكة العربية السعودية على الامتثال لنظام حماية البيانات الشخصية (PDPL) ومتطلبات الهيئة الوطنية للأمن السيبراني (NCA).

المتطلبات المسبقة

  • خادم لينكس (Ubuntu 22.04/24.04 أو Debian أو عائلة RHEL) مثبّت عليه MySQL 8.0.
  • مستخدم يملك صلاحية sudo وحساب MySQL بصلاحيات إدارية.
  • حِمل عمل حقيقي أو تمثيلي — فالضبط على قاعدة بيانات خاملة لا يخبرك بشيء.

غيّر متغيراً واحداً في كل مرة ثم أعد القياس دائماً. الضبط دون قياس مجرد تخمين.

الخطوة الأولى — القياس أولاً عبر سجل الاستعلامات البطيئة

لا يمكنك ضبط ما لا تقيسه. يسجّل سجل الاستعلامات البطيئة كل عبارة تتجاوز عتبة زمنية محددة، وهو أسرع طريقة للعثور على أسوأ الاستعلامات لديك.

فعّله أثناء التشغيل (دون الحاجة لإعادة التشغيل):

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;            -- سجّل الاستعلامات الأبطأ من ثانية واحدة
SET GLOBAL log_queries_not_using_indexes = 'ON';

ولجعله دائماً، أضف ما يلي إلى ملف إعدادات MySQL (/etc/mysql/mysql.conf.d/mysqld.cnf على Ubuntu/Debian، أو /etc/my.cnf على RHEL):

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1

اترك حِمل عمل تمثيلياً يعمل، ثم حلّل السجل. تقوم أداة pt-query-digest من حزمة Percona Toolkit بتجميع الاستعلامات المتطابقة حسب بصمتها وترتيبها بحسب إجمالي الوقت المستهلك:

sudo apt install percona-toolkit   # على Debian/Ubuntu
pt-query-digest /var/log/mysql/mysql-slow.log | less

ركّز على الاستعلامات في أعلى التقرير — تلك ذات أعلى إجمالي زمن تنفيذ، وليس فقط أعلى زمن للتشغيل الواحد. فتحسين استعلام يعمل 10,000 مرة في الدقيقة أجدى من تحسين استعلام يعمل ليلاً مرة واحدة.

الخطوة الثانية — ضبط حجم InnoDB Buffer Pool

InnoDB هو محرك التخزين الافتراضي، ويقوم الـ buffer pool الخاص به بتخزين بيانات الجداول والفهارس في الذاكرة العشوائية (RAM). فإذا كانت مجموعة العمل لديك تتسع داخل الـ buffer pool، فإن MySQL يخدم معظم عمليات القراءة من الذاكرة بدل القرص — وهو عادةً أكبر مكسب منفرد.

تحقق من الحجم الحالي ونسبة الإصابة (hit ratio):

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';

SELECT
  (1 - (SELECT VARIABLE_VALUE FROM performance_schema.global_status
        WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads')
      / NULLIF((SELECT VARIABLE_VALUE FROM performance_schema.global_status
        WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests'), 0)) * 100
  AS hit_ratio_pct;

استهدف نسبة إصابة تبلغ 99% أو أعلى. ووفقاً لوثائق Oracle، اضبط الـ buffer pool على 50–75% من إجمالي الذاكرة العشوائية على خادم قاعدة بيانات مخصص، مع ترك مساحة لنظام التشغيل ولمخازن MySQL الأخرى (فـ InnoDB نفسه يحجز نحو 10% إضافية فوق الحجم المُعدّ). أما على خادم مشترك صغير، فابقَ أقرب إلى 50% واترك على الأقل 1–2 جيجابايت لنظام التشغيل.

بالنسبة لخادم مخصص بسعة 8 جيجابايت، يُعد نحو 5–6 جيجابايت نقطة انطلاق معقولة:

[mysqld]
innodb_buffer_pool_size = 5G

أعد تشغيل MySQL وأعد فحص نسبة الإصابة بعد أن يُحمّي حِمل العمل ذاكرة التخزين المؤقت. ولا تبالغ في الحجم: فإذا تجاوز الـ buffer pool مع بقية العمليات حجم الذاكرة العشوائية، فإن نظام التشغيل يلجأ إلى التبديل (swap) على القرص فينهار الأداء.

الخطوة الثالثة — قراءة خطط الاستعلام عبر EXPLAIN

بعد معرفة الاستعلامات البطيئة، اكتشف السبب. يُظهر الأمر EXPLAIN كيف ينوي MySQL تنفيذ العبارة:

EXPLAIN SELECT * FROM orders WHERE customer_id = 42 AND status = 'shipped';

أهم الأعمدة التي ينبغي مراقبتها:

العمود ما الذي تنتبه إليه
type القيمة ALL تعني مسحاً كاملاً للجدول — وهي غالباً سيئة. يُفضّل ref أو range أو const.
key الفهرس المستخدَم. القيمة NULL تعني عدم استخدام أي فهرس.
rows العدد المقدّر للصفوف المفحوصة. الأقل أفضل.
Extra تشير Using filesort أو Using temporary إلى خطوات فرز مكلفة.

في MySQL 8.0 يمكنك المضي أبعد عبر EXPLAIN ANALYZE، الذي ينفّذ الاستعلام فعلياً ويُبلّغ بأزمنة حقيقية إلى جانب التقديرات:

EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 42 AND status = 'shipped';

هذه أكثر طريقة موثوقة للتأكد مما إذا كان تغيير الفهرس قد أفاد فعلاً.

الخطوة الرابعة — إضافة الفهارس المناسبة

المسح الكامل للجدول (type: ALL) على جدول كبير هو السبب الكلاسيكي للاستعلامات البطيئة. أضف فهرساً على الأعمدة المستخدمة في جُمل WHERE وJOIN وORDER BY.

بالنسبة للاستعلام أعلاه، يتيح فهرس مركّب يغطي العمودين المُرشَّحين لـ MySQL القفز مباشرةً إلى الصفوف المطابقة:

CREATE INDEX idx_orders_customer_status
  ON orders (customer_id, status);

ترتيب الأعمدة مهم: ضع العمود الأكثر انتقائيةً — أو المستخدَم في مطابقات المساواة — أولاً. كما يخدم الفهرس المركّب الاستعلامات التي ترشّح على العمود القائد وحده (customer_id)، لذا نادراً ما تحتاج إلى فهرس منفصل أحادي العمود له.

أعد تشغيل EXPLAIN ANALYZE للتأكد من تحسّن type (مثلاً من ALL إلى ref) وأن قيمة rows انخفضت انخفاضاً حاداً.

الفهارس ليست مجانية — فهي تستهلك مساحة على القرص وتبطئ عمليات الكتابة (INSERT/UPDATE/DELETE)، إذ يجب صيانة كل فهرس. ففهرِس بتأنٍّ، وأزل الفهارس غير المستخدمة التي يمكنك التعرف عليها عبر عرض sys.schema_unused_indexes:

SELECT * FROM sys.schema_unused_indexes;

الخطوة الخامسة — التحقق ثم التكرار

الضبط حلقة متكررة وليس عملاً يُنجز مرة واحدة. بعد كل تغيير:

  1. أعد تشغيل الاستعلام المتأثر باستخدام EXPLAIN ANALYZE وقارن الأزمنة.
  2. اترك سجل الاستعلامات البطيئة يعمل مرة أخرى وأعد تحليله بأداة الـ digest.
  3. تأكد من أن نسبة إصابة الـ buffer pool ظلت مرتفعة.

تراجع عن أي تغيير لم يُفِد. واحتفظ بملاحظات عمّا غيّرته ولماذا — فأنت في المستقبل ستشكر نفسك في الحاضر.

أخطاء شائعة

  • ضبط استعلام واحد بمعزل عن غيره. حسّن وفق الأثر الإجمالي (التكرار × التكلفة)، وهو ما يكشفه تحليل سجل الاستعلامات البطيئة.
  • نسخ قيم my.cnf من المدونات. حجم الـ buffer pool يعتمد على ذاكرتك العشوائية ومجموعة بياناتك أنت. فقِس ولا تنسخ.
  • تغليف الأعمدة المفهرسة بدوال. فالعبارة WHERE DATE(created_at) = '2026-06-08' لا تستطيع استخدام فهرس على created_at؛ أعد كتابتها كنطاق: WHERE created_at >= '2026-06-08' AND created_at < '2026-06-09'.
  • استخدام SELECT * على جداول عريضة. اجلب الأعمدة التي تحتاجها فقط كي يتمكن MySQL من استخدام الفهارس المُغطِّية (covering indexes).

الخلاصة

ضبط أداء MySQL عملٌ منهجي وليس سحراً: قِس عبر سجل الاستعلامات البطيئة، وامنح InnoDB ذاكرة عشوائية كافية، واقرأ خطط الاستعلام بـ EXPLAIN ANALYZE، وأضف الفهارس بتأنٍّ. هذه الأساسيات الأربعة تحل غالبية حالات البطء الواقعية قبل الحاجة إلى أي ترقية للأجهزة.

أما الأحمال التي تحتاج إلى توسّع أو زمن استجابة يمكن التنبؤ به أو دعم محلي بالعربية، فاستضف قواعد بياناتك داخل المملكة. استكشف خوادم VPS والخوادم السحابية من سكايلاين كلاود، واقرنها بـ استضافة البريد الإلكتروني للأعمال لمنظومة متكاملة، ثم أنشئ حسابك في سكايلاين كلاود لتنشر خادم MySQL مضبوطاً خلال دقائق.

SKYLINE Engineering

@skyline

The engineering team at SKYLINE Industrial Solutions. We publish field-tested guides drawn from real KSA and GCC deployments.

See author profile
SKYLINE engineering services

Need this implemented for you?

Reading is free — building it right takes a team. SKYLINE engineers ship Skyline Cloud for Aramco vendors, banks, hospitals and government agencies across Saudi Arabia. Talk to us before you start.

Aramco Approved Contractor ISO 9001 · ISO 27001 SAMA CSF aligned NCA ECC ready 247+ KSA clients

Comments

0 total · 0 threads
Be the first to leave a comment.