JOIN، مع مجموعة واسعة من خوارزميات الربط. ولتحقيق أقصى أداء، نوصي باتباع اقتراحات تحسين JOIN الواردة في هذا الدليل.
- للحصول على أفضل أداء، ينبغي أن تسعى إلى تقليل عدد عمليات
JOINفي الاستعلامات، خاصةً في أحمال العمل التحليلية في الوقت الفعلي التي تتطلب أداءً بزمن استجابة في حدود المللي ثانية. استهدف حدًا أقصى من 3 إلى 4 عملياتJOINفي الاستعلام الواحد. ونفصّل عددًا من التغييرات لتقليل عمليات الربط في قسم نمذجة البيانات، بما في ذلك إلغاء التطبيع، وDictionaries، والعروض المادية. - اعتبارًا من ClickHouse 24.12، يعيد مُخطِّط الاستعلام تلقائيًا ترتيب عمليات الربط بين جدولين بحيث يضع الجدول الأصغر على الجانب الأيمن لتحقيق أفضل أداء. وفي الإصدار 25.9، تم توسيع ذلك لتحسين ترتيب عمليات الربط في الاستعلامات التي تربط بين ثلاثة جداول أو أكثر.
- إذا كان استعلامك يتطلب ربطًا مباشرًا، أي
LEFT ANY JOIN، كما هو موضح أدناه، فنوصي باستخدام Dictionaries حيثما أمكن.
- إذا كنت تُجري عمليات ربط داخلية، فغالبًا ما يكون من الأفضل كتابتها على هيئة استعلامات فرعية باستخدام العبارة
IN. انظر إلى الاستعلامات التالية، وهي متكافئة وظيفيًا. فكلاهما يعثر على عددpostsالتي لا تذكر ClickHouse في السؤال، لكنها تذكره فيcomments.
ANY INNER JOIN بدلًا من INNER JOIN فقط، لأننا لا نريد الناتج الديكارتي؛ أي نريد مطابقة واحدة فقط لكل منشور.
يمكن إعادة كتابة هذا الـ JOIN باستخدام استعلام فرعي، مما يحسّن الأداء بشكل كبير:
JOIN والاستعلامات الفرعية، فإننا نوصي المستخدمين دائمًا بتطبيق الشروط يدويًا على جميع البنود الفرعية حيثما أمكن، لتقليل حجم البيانات المرسلة إلى JOIN إلى أدنى حد. تأمل المثال التالي، حيث نريد حساب عدد الأصوات المؤيدة للمنشورات المتعلقة بـ Java منذ عام 2020.
يكتمل استعلام ساذج، مع وضع الجدول الأكبر على الجانب الأيسر، في 56 ثانية:
INNER JOIN إلى استعلام فرعي، كما أُشير سابقًا، مع الإبقاء على شرط التصفية في كلٍّ من الاستعلام الخارجي والداخلي.
اختيار خوارزمية JOIN
تحدّد هذه الخوارزميات كيفية تخطيط استعلام JOIN وتنفيذه. وبشكل افتراضي، يستخدم ClickHouse خوارزمية direct أو hash JOIN استنادًا إلى نوع JOIN المستخدم وقيمة strictness ومحرك الجداول التي يجري ضمّها. وبدلًا من ذلك، يمكن تهيئة ClickHouse لاختيار خوارزمية JOIN بشكل تكيّفي وتغييرها ديناميكيًا في وقت التشغيل، بحسب توافر الموارد واستخدامها: فعندما تكون
join_algorithm=auto، يجرّب ClickHouse أولًا خوارزمية hash JOIN، وإذا تم تجاوز حد الذاكرة الخاص بهذه الخوارزمية، تُستبدل الخوارزمية أثناء التنفيذ بـ partial merge JOIN. ويمكنك معرفة الخوارزمية التي تم اختيارها عبر trace logging. كما يتيح لك ClickHouse أيضًا تحديد خوارزمية JOIN المطلوبة بنفسك من خلال الإعداد join_algorithm.
تُعرض أدناه أنواع JOIN المدعومة لكل خوارزمية JOIN، وينبغي أخذها في الاعتبار قبل إجراء التحسين:
يمكن العثور على وصف تفصيلي كامل لكل خوارزمية
JOIN هنا، بما في ذلك مزاياها وعيوبها وخصائص التوسّع الخاصة بها.
يعتمد اختيار خوارزميات JOIN المناسبة على ما إذا كنت تسعى إلى التحسين من حيث الذاكرة أو الأداء.
تحسين أداء JOIN
-
(1) إذا كان يمكن تحميل بيانات الجدول الموجود على الجانب الأيمن مسبقًا إلى بنية بيانات مفتاح-قيمة داخل الذاكرة منخفضة الكمون، مثل القاموس، وكان مفتاح الـ JOIN يطابق سمة المفتاح في مخزن المفتاح-القيمة الأساسي، وكانت دلالات
LEFT ANY JOINكافية، فإن direct JOIN تكون مناسبة وتوفّر أسرع نهج. - (2) إذا كان الترتيب المادي للصفوف في جدولك يطابق ترتيب فرز مفتاح الـ JOIN، فالأمر يعتمد على الحالة. في هذه الحالة، تتخطى full sorting merge JOIN مرحلة الفرز، مما يؤدي إلى خفض كبير في استخدام الذاكرة، وقد يوفّر أيضًا، بحسب حجم البيانات وتوزيع قيم أعمدة مفتاح الـ JOIN، زمن تنفيذ أسرع من بعض خوارزميات hash JOIN.
- (3) إذا كان الجدول الأيمن يتّسع في الذاكرة، حتى مع العبء الإضافي على استخدام الذاكرة في parallel hash JOIN، فقد تكون هذه الخوارزمية أو hash JOIN أسرع. ويعتمد ذلك على حجم البيانات وأنواع البيانات وتوزيع قيم أعمدة مفتاح الـ JOIN.
- (4) إذا كان الجدول الأيمن لا يتّسع في الذاكرة، فالأمر يعتمد مرة أخرى. يوفّر ClickHouse ثلاث خوارزميات JOIN غير مقيّدة بالذاكرة. وجميعها تقوم مؤقتًا بترحيل البيانات إلى القرص. تتطلّب full sorting merge JOIN وpartial merge JOIN فرز البيانات مسبقًا. أما Grace hash JOIN فتبني جداول hash من البيانات بدلًا من ذلك. وبحسب حجم البيانات وأنواع البيانات وتوزيع قيم أعمدة مفتاح الـ JOIN، قد توجد حالات يكون فيها بناء جداول hash من البيانات أسرع من فرز البيانات، والعكس صحيح.
التحسين من حيث الذاكرة
JOIN لتحقيق أقل استهلاك ممكن للذاكرة بدلًا من أسرع وقت تنفيذ، فيمكنك استخدام شجرة القرار التالية بدلًا من ذلك:
- (1) إذا كان الترتيب الفعلي للصفوف في
tableلديك يطابق ترتيب فرز مفتاح الـ JOIN، فإن استهلاك الذاكرة في full sorting merge JOIN يكون عند أدنى مستوى ممكن. وتتمثل فائدة إضافية في الحصول على سرعةJOINجيدة لأن مرحلة الفرز تكون معطلة. - (2) يمكن ضبط grace hash JOIN لتحقيق استهلاك منخفض جدًا للذاكرة من خلال تهيئة عدد كبير من buckets، ولكن على حساب سرعة
JOIN. ويستخدم partial merge JOIN عمدًا مقدارًا قليلًا من الذاكرة الرئيسية. وبوجه عام، يستخدم full sorting merge JOIN مع تفعيل الفرز الخارجي ذاكرةً أكبر من partial merge JOIN (على افتراض أن ترتيب الصفوف لا يطابق ترتيب فرز المفتاح)، مقابل ميزة تحسن كبير في وقت تنفيذJOIN.