PmaControl logo PmaControl
  • مرحباً
  • PmaControl
    • وكلاء الذكاء الاصطناعي 13 وكلاء محليين
    • عروضنا المجتمع، السحابة، محليًا، المميز
    • التوثيق أدلة، API، الهندسة المعمارية
    • السوق المكونات الإضافية للمجتمع
    • عملاء أكثر من 28 شركة
    • الأسئلة الشائعة 25 سؤالا / 7 فئات
    قواعد البيانات
    • ماريا دي بي 31 مادة
    • ماي إس كيو إل 11 مادة
    • مجموعة جاليرا 6 عناصر
    • ماكس سكيل 3 عناصر
    • ProxySQL 2 عناصر
    • أمازون أورورا ماي إس كيو إل 0 العناصر
    • قاعدة بيانات أزور 0 العناصر
    • انقر البيت 0 العناصر
    • GCP CloudSQL 0 العناصر
    • بيركوناسيرفر 0 العناصر
    • متجر واحد 0 العناصر
    • تي دي بي 0 العناصر
    • سرعة 0 العناصر
    الحلول
    • دعم 24 × 7 حالات الطوارئ MariaDB وMySQL
    • Observabilité SQL المراقبة والتنبيهات والطوبولوجيا
    • Haute disponibilité النسخ المتماثل، تجاوز الفشل، جاليرا
    • Disaster Recovery النسخ الاحتياطي والاستعادة، RPO/RTO
    • Sécurité & conformité التدقيق، اللائحة العامة لحماية البيانات، SOC2
    • Migration & upgrade صفر توقف عن العمل، pt-osc، gh-ost
  • عروضنا
  • موارد
    • التوثيق الأدلة الفنية وواجهات برمجة التطبيقات
    • مركز تحسين MySQL مؤشر تخفيض السعر والمقاييس والإعدادات والحوادث
    • الأسئلة الشائعة 25 سؤالا متكررا
    • الشهادات ملاحظات العملاء وحالات الاستخدام
    • مدونة مقالات ورؤى
    • خريطة الطريق الميزات القادمة
    مجالات الخبرة
    • Observabilité SQL المراقبة والتنبيهات وطوبولوجيا Dot3
    • Haute disponibilité النسخ المتماثل، تجاوز الفشل، جاليرا
    • Sécurité & conformité التدقيق، اللائحة العامة لحماية البيانات، SOC2، ISO 27001
    • Disaster Recovery النسخ الاحتياطي والاستعادة، RPO/RTO
    • Performance & optimisation ملخصات، شرح، ضبط
    • Migration & upgrade صفر توقف عن العمل، pt-osc
    روابط سريعة
    • جيثب ويكي 26 صفحة - التثبيت والمحرك والمكونات الإضافية
    • كود المصدر مستودع جيثب الرسمي
    • دعم 24 × 7 حالات الطوارئ MariaDB وMySQL
    • احجز عرضًا توضيحيًا 30 دقيقة - هندسة معمارية حقيقية
  • دعم 24 × 7
  • احجز عرضًا توضيحيًا
احجز عرضًا توضيحيًا
🇫🇷 FR Français 🇬🇧 EN English 🇵🇱 PL Polski 🇷🇺 RU Русский 🇨🇳 ZH 中文 🇸🇦 AR العربية
← العودة إلى بلوق

لقد تغلبت على مُحسِّن MariaDB: من 94 ثانية إلى 55 مللي ثانية

تم النشر بتاريخ 15 يوليو 2025 بواسطة Sylvain ARBAUDIE
mariadb optimizer performance sql
يشارك X LinkedIn Facebook Email PDF
لقد تغلبت على مُحسِّن MariaDB: من 94 ثانية إلى 55 مللي ثانية

السياق: الترحيل MySQL 8 إلى MariaDB 11.4

مشروع الترحيل من MySQL 8 إلى MariaDB 11.4 يسير بشكل جيد بشكل عام. الاختبارات الوظيفية باللون الأخضر، واختبارات الأداء أيضًا - باستثناء استعلام واحد. طلب واحد استغرق ثانيتين في MySQL 8 ويستغرق الآن 94 ثانية في MariaDB 11.4.

هذا هو انحدار الترحيل الكلاسيكي: لقد تباعدت مُحسِّنات MariaDB وMySQL بشكل ملحوظ منذ الانقسام. إن خطة التنفيذ التي نجحت على أحدها قد تكون كارثية على الآخر.

الاستعلام الإشكالي

يستخدم الاستعلام الأصلي نمط LEFT JOIN الكلاسيكي للعثور على السجلات غير الموجودة في جدول آخر:

SELECT p.product_id, p.product_name, p.category_id
FROM products p
LEFT JOIN discontinued_products dp
    ON p.product_id = dp.product_id
    AND p.category_id = dp.category_id
WHERE dp.product_id IS NULL
  AND p.status = 'active'
  AND p.created_at >= '2023-01-01';

النية واضحة: العثور على جميع المنتجات النشطة غير المدرجة في جدول المنتجات المتوقفة. هذا هو نمط "مكافحة الانضمام" الذي يتم تنفيذه عبر LEFT JOIN + IS NULL.

لماذا 94 ثانية؟

يكشف تحليل خطة التنفيذ على MariaDB 11.4 عن المشكلة. يختار المحسن ما يلي:

  1. قم بمسح الجدول products باستخدام الفهرس الموجود في status (200000 صف)
  2. لكل صف، قم بمسح الجدول discontinued_products للتحقق من عدم وجود تطابقات

مع جدول discontinued_products يتكون من 17500 صف، يمثل هذا حوالي 3.5 مليار مقارنة. اختار مُحسِّن MySQL 8 خطة مختلفة ذات صلة تجزئة، وهي أكثر كفاءة لهذا النمط.

المشكلة الأساسية ليست في المُحسِّن MariaDB — بل في الاستعلام نفسه. إن LEFT JOIN + IS NULL لتنفيذ منع الانضمام هو نمط مضاد تاريخي يعود تاريخه إلى الوقت الذي لم يكن لدى SQL فيه بدائل أفضل.

الحل: CTE + باستثناء

يدعم MariaDB تعبيرات الجدول الشائعة (CTE) منذ الإصدار 10.2 وعامل التشغيل EXCEPT منذ الإصدار 10.3. تسمح لك هاتان الميزتان بإعادة كتابة المنطق بطريقة أكثر وضوحًا:

WITH active_products AS (
    SELECT product_id, category_id
    FROM products
    WHERE status = 'active'
      AND created_at >= '2023-01-01'
),
still_active AS (
    SELECT product_id, category_id FROM active_products
    EXCEPT
    SELECT product_id, category_id FROM discontinued_products
)
SELECT p.product_id, p.product_name, p.category_id
FROM products p
JOIN still_active sa
    ON p.product_id = sa.product_id
    AND p.category_id = sa.category_id;

لماذا هو أسرع

  1. CTE active_products يجسد 200000 منتج نشط في الذاكرة. مسح واحد للجدول products.

  2. يقوم عامل التشغيل EXCEPT بتنفيذ عملية محددة: فهو يأخذ جميع المنتجات النشطة ويطرح تلك التي تظهر في discontinued_products. هذا فرق مجموعة قائم على التجزئة، وليس مقارنة سطرًا بسطر.

  3. الانضمام النهائي مع CTE still_active هو بحث بسيط عن مجموعة تمت تصفيتها بالفعل.

النتيجة: 55 مللي ثانية

متري الانضمام الأيسر CTE + باستثناء تحسين
الوقت 94 ثانية 55 مللي ثانية 1700x
مقارنات ~3.5 مليار ~217,500 99.99%
النهج سطراً سطراً مصمم الفرقة —

من 94 ثانية إلى 55 مللي ثانية. عامل 1,700. ليس عن طريق تغيير إعداد التكوين. ليس عن طريق إضافة فهرس. من خلال إعادة التفكير في منطق الاستعلام.

الانضمام الأيسر المضاد للنمط: لماذا يستمر

نمط LEFT JOIN + IS NULL لمكافحة الانضمام موجود في كل مكان. يمكن العثور عليها في البرامج التعليمية والدورات التدريبية عبر الإنترنت وإجابات Stack Overflow. ويستمر لعدة أسباب:

التاريخ: قبل SQL:1999، لم يكن هناك EXCEPT، ولا NOT EXISTS محسّن، ولا CTE. كان LEFT JOIN + IS NULL هو الخيار المحمول الوحيد.

العادة: يتعلم المطورون النمط الناجح ويعيدون استخدامه. "إنه يعمل" هو عدو "إنه الأمثل".

التوافق: تعمل LEFT JOIN على جميع إصدارات جميع أنظمة إدارة قواعد البيانات (DBMS). EXCEPT مدعوم فقط في الإصدارات الحديثة.

البدائل التي يجب معرفتها

بالنسبة لمكافحة الانضمام، توجد ثلاثة بدائل:

غير موجود (غالبًا ما يكون الخيار الأفضل)

SELECT p.product_id, p.product_name, p.category_id
FROM products p
WHERE p.status = 'active'
  AND p.created_at >= '2023-01-01'
  AND NOT EXISTS (
    SELECT 1 FROM discontinued_products dp
    WHERE dp.product_id = p.product_id
      AND dp.category_id = p.category_id
  );

تم تحسين NOT EXISTS بشكل جيد بواسطة المحركين MariaDB وMySQL. يمكن للمُحسِّن استخدام شبه صلة عكسية، وهي أكثر كفاءة من الصلة اليسرى.

ليس في (احترس من القيم الخالية)

SELECT product_id, product_name, category_id
FROM products
WHERE status = 'active'
  AND created_at >= '2023-01-01'
  AND (product_id, category_id) NOT IN (
    SELECT product_id, category_id
    FROM discontinued_products
  );

تحذير: NOT IN له سلوك صعب مع القيم NULL. إذا كان من الممكن أن يكون discontinued_products.product_id NULL، فإن دلالات NOT IN تُرجع نتيجة فارغة. استخدم دائمًا NOT EXISTS إذا كانت القيم الخالية ممكنة.

باستثناء (الأكثر قابلية للقراءة)

SELECT product_id, category_id FROM products
WHERE status = 'active' AND created_at >= '2023-01-01'
EXCEPT
SELECT product_id, category_id FROM discontinued_products;
`

EXCEPT` هو أنقى تعبير عن العملية المحددة "A ناقص B". ولكنها تُرجع فقط أعمدة العملية، وليس الأعمدة الإضافية - وبالتالي تستخدم CTE لإعادة تقديم الأعمدة المفقودة عبر JOIN.

العبرة

المحسن هو أداة، وليس معجزة. عندما يكون الاستعلام بطيئًا، يجب ألا يكون السؤال الأول هو "ما التلميح الذي يمكنني إضافته؟" أو "ما هو الإعداد الذي يجب أن أغيره؟". يجب أن يكون السؤال الأول: هل يعبر طلبي بشكل صحيح عن نيتي؟

A LEFT JOIN + IS NULL يعبر عن "الانضمام ثم تصفية العناصر غير المتطابقة". يعبر EXCEPT مباشرة عن "طرح هذه المجموعة من هذه المجموعة الأخرى". الصيغة الثانية أقرب إلى نية العمل، وتعطي المحسن فرصة أفضل بكثير للعثور على خطة فعالة.

تغلب على المحسن من خلال التفكير كعالم رياضيات، وليس مبرمجًا.


تم نشر هذه المقالة في الأصل على متوسط.

يشارك X LinkedIn Facebook Email PDF
← العودة إلى بلوق

تعليقات (0)

لا توجد تعليقات حتى الآن.

اترك تعليقا

PmaControl
+33 6 63 28 27 47 contact@pmacontrol.com
إشعارات قانونية GitHub اتصال
لا تنتظر وقوع الحادث حتى تفهم هندستك المعمارية. © 2014-2026 PmaControl — 68Koncept