join_algorithm
- يصبح استدلال النوع لـ join key أكثر صرامة (فعلى سبيل المثال، لا يمكن لـ merge join ضم مفاتيح من أنواع مختلفة مثل
StringوNullable(String)). قد يغيّر ذلك الأنواع الناتجة لأعمدةUSING، وقد يؤدي إلى فشل join مع table ذات engine من نوعJoinبسببTYPE_MISMATCH. يتم تفعيله بواسطةfull_sorting_mergeوparallel_full_sorting_merge. - يحصل
ORDER BY ... LIMITعلى الجانب المحفوظ من join على sort صريح بدلًا من قراءة بترتيب primary key، لأن join يُفترض أنه يقطع القراءة المرتبة (تُدرج merge join sort خاصًا بها قبل join؛ وتُعيد partial merge join فرز blocks اليسرى؛ كما أن join التي يمكنها إنتاج blocks مؤجلة لا تنشر القراءة المرتبة أيضًا). تكون النتيجة نفسها، لكن plan أقل كفاءة. يتم تفعيله بواسطةfull_sorting_mergeوparallel_full_sorting_mergeوpartial_mergeوprefer_partial_mergeوgrace_hashوauto، وكذلك بواسطة قيمة غير صفرية لـmax_bytes_before_external_join/max_bytes_ratio_before_external_join.
hash أو خوارزمية أخرى. إذا كان ذلك غير مرغوب فيه، فلا تدرج الخوارزميات المذكورة أعلاه في join_algorithm للاستعلامات المتأثرة.
القيم الممكنة:
- grace_hash
grace_hash_join_initial_buckets). ويُنفَّذ ذلك بطريقة تضمن إمكانية معالجة كل bucket بشكل مستقل. تُضاف rows من الـ bucket الأولى إلى hash table داخل الذاكرة، بينما تُحفَظ البقية على disk. وإذا تجاوز نمو hash table مقدار memory limit (على سبيل المثال كما هو محدد بواسطة max_bytes_in_join)، فسيُزاد عدد الـ buckets ويُعاد تحديد الـ bucket المخصصة لكل row. وأي rows لا تنتمي إلى الـ bucket الحالية تُفرَّغ وتُعاد إعادة تخصيصها.
يدعم INNER/LEFT/RIGHT/FULL ALL/ANY JOIN.
- hash
OR في قسم JOIN ON.
عند استخدام خوارزمية hash، يُحمَّل الجزء الأيمن من JOIN إلى RAM.
- parallel_hash
hash يقسّم البيانات إلى buckets ويبني عدة hash tables بدلًا من واحدة، بالتوازي، لتسريع هذه العملية.
عند استخدام خوارزمية parallel_hash، يُحمَّل الجزء الأيمن من JOIN إلى RAM.
- partial_merge
RIGHT JOIN وFULL JOIN إلا مع strictness من نوع ALL (SEMI وANTI وANY وASOF غير مدعومة).
عند استخدام خوارزمية partial_merge، يقوم ClickHouse بفرز البيانات وتفريغها إلى disk. تختلف خوارزمية partial_merge في ClickHouse قليلًا عن التطبيق التقليدي. أولًا، يفرز ClickHouse الجدول الأيمن حسب join keys على هيئة blocks، ثم ينشئ min-max index للـ blocks المرتبة. بعد ذلك يفرز أجزاءً من الجدول الأيسر حسب join key ويجري join عليها مع الجدول الأيمن. ويُستخدم min-max index أيضًا لتخطي blocks غير اللازمة من الجدول الأيمن.
- direct
direct (المعروفة أيضًا باسم nested loop) عملية lookup في الجدول الأيمن باستخدام rows من الجدول الأيسر كمفاتيح.
وهي مدعومة في أنواع تخزين خاصة مثل Dictionary وEmbeddedRocksDB وtables من نوع MergeTree.
بالنسبة إلى MergeTree tables، تدفع الخوارزمية مرشحات join key مباشرةً إلى storage layer. وقد يكون ذلك أكثر كفاءة عندما يتمكن المفتاح من استخدام primary key index الخاص بالجدول في عمليات lookup، وإلا فإنها تُجري فحصًا كاملًا للجدول الأيمن لكل block من الجدول الأيسر.
يدعم INNER وLEFT joins، وjoin keys أحادية العمود للمساواة فقط، من دون شروط أخرى.
- auto
auto، تتم تجربة join hash أولًا، ثم يجري التبديل تلقائيًا أثناء التنفيذ إلى خوارزمية أخرى إذا تم تجاوز memory limit.
- full_sorting_merge
- ie_join
JOIN يحتوي قسم ON فيه على مقارنتين لعدم المساواة (< و<= و> و>=) بين تعبيرات الجداول الموصولة. تدعم ALL INNER/LEFT/RIGHT/FULL JOIN وSEMI/ANTI LEFT/RIGHT JOIN.
يحدد موضعها في القائمة الأولوية: فإذا أُدرجت بعد الخوارزميات الأخرى، فلا تُستخدم IEJoin إلا عندما لا تنطبق تلك الخوارزميات (أي عندما لا يحتوي قسم ON على شروط مساواة)؛ وإذا أُدرجت أولًا، فتُستخدم كلما احتوى قسم ON على شرطي عدم مساواة. تُطبَّق الشروط المتبقية (بما فيها شروط المساواة) كـ filter على نتيجة join بالنسبة إلى ALL INNER JOIN، وتُقيَّم داخل operator كشرط متبقٍ يؤثر في المطابقة للأنواع الأخرى. من دون ie_join في القائمة، يُنفَّذ INNER JOIN الذي لا يحتوي إلا على شروط عدم مساواة بوصفه CROSS JOIN مع filter، ولا تُدعَم الأنواع الأخرى.
يُراكَم كلا الإدخالين في الذاكرة قبل تنفيذ join: يحدّ max_rows_in_join وmax_bytes_in_join إجمالي الإدخال المتراكم لكلا الجانبين معًا (وليس الجانب الأيمن فقط)، ويُحدَّد الإجراء عند overflow بواسطة join_overflow_mode؛ ولا تُحتسب sort indexes التي يبنيها operator فوق الإدخال المتراكم ضمن الحد. يعمل join operator نفسه في thread واحد؛ ولا يُنفَّذ بالتوازي إلا الفرز السابق لـ join للإدخالين.
- parallel_full_sorting_merge
full_sorting_merge، إلا أن joins المساواة المتوافقة مع hash تُقسَّم إلى shards بحسب hash الخاص بـ join keys، لتكوين merge joins مستقلة لكل shard تعمل بالتوازي (حتى max_threads) بدلًا من merge join واحدة. يحافظ ذلك على الاستخدام المنخفض والمتدفق للذاكرة في merge join مع استخدام جميع threads، ولا تكون النتيجة مرتبة.
لا يُطبَّق التقسيم إلى shards باستخدام hash الخاص بـ join keys إلا على joins المساواة البسيطة لأنواع المفاتيح التي يتوافق hash الخاص بها مع مقارنة merge-join، وفقط عندما لا يكون أي من الجانبين مرتبًا مسبقًا. ويُتخطى في الحالات التالية:
- joins من نوع
ASOF، وأنواع المفاتيح floating-point وJSONوObjectوDynamic: إذ لا تتسق hashes الخاصة بها مع مقارنة merge-join، ولذلك قد تصل المفاتيح المتساوية إلى shards مختلفة. - الجوانب المرتبة مسبقًا (قراءة MergeTree بالترتيب، أو أي إدخال مرتب مسبقًا): قد يؤدي scatter المحافظ على الترتيب إلى merge joins لكل shard إلى حدوث deadlock في pipeline. ويُحتفَظ بدلًا من ذلك بالقراءة بالترتيب وتحسينها
read_in_order_use_virtual_row. - أثناء قيام initiator ببناء distributed plan (
make_distributed_plan)، لأن scattered sort غير قابل للتسلسل من أجل التنفيذ عن بُعد. تُعيد local single-fragment plan وfragments الخاصة بكل worker التحسين مع تعطيل ذلك الإعداد، ولذلك لا يزال بإمكانها التقسيم إلى shards.
full_sorting_merge واحدة، ولا يزال بإمكان جوانب MergeTree المقروءة بالترتيب أن تُقسَّم إلى shards عند المصدر بحسب primary-key ranges (التي ترتب بالمقارنة نفسها التي تستخدمها join، لذا تبقى المفاتيح المتساوية معًا) عند تمكين query_plan_join_shard_by_pk_ranges.
- prefer_partial_merge
partial_merge إن أمكن، وإلا يستخدم hash. Deprecated، وهو مماثل لـ partial_merge,hash.
- default (مهمل)
direct,hash، أي جرّب استخدام direct join وhash join (بهذا الترتيب).
join_any_take_last_row
ANY عندما يحتوي الجدول الأيمن على أكثر من صف مطابق واحد للمفتاح.
ينطبق هذا الإعداد على جداول محرك
Join وخوارزميات JOIN المعتمدة على hash.إذا تم إنشاء JOIN بالتوازي، فقد يصبح ترتيب الصفوف غير حتمي. وهذا يعني أن join_any_take_last_row = 1 قد يعيد صفًا غير حتمي في استعلامات ANY JOIN.- 0 — إذا كان الجدول الأيمن يحتوي على أكثر من صف مطابق واحد، فلن يُضم إلا أول صف يتم العثور عليه.
- 1 — إذا كان الجدول الأيمن يحتوي على أكثر من صف مطابق واحد، فلن يُضم إلا آخر صف يتم العثور عليه.
join_default_strictness
ALL— إذا كان الجدول الأيمن يحتوي على عدة صفوف متطابقة، ينشئ ClickHouse حاصلًا كارتيسيًا من الصفوف المتطابقة. وهذا هو سلوكJOINالمعتاد في standard SQL.ANY— إذا كان الجدول الأيمن يحتوي على عدة صفوف متطابقة، فلا يُضم سوى أول صف يُعثر عليه. وإذا كان الجدول الأيمن يحتوي على صف متطابق واحد فقط، فستكون نتائجANYوALLمتطابقة.ASOF— لربط التسلسلات ذات المطابقة غير المؤكدة.Empty string— إذا لم يتم تحديدALLأوANYفي الاستعلام، يطرح ClickHouse استثناء.
join_on_disk_max_files_to_merge
- أي عدد صحيح موجب يبدأ من 2.
join_output_by_rowlist_perkey_rows_threshold
join_overflow_mode
join_algorithm hash وparallel_hash وie_join.
أما الخوارزميات الأخرى (مثل partial_merge وgrace_hash وauto) فتتعامل مع
هذه الحدود بطريقة مختلفة — مثل تفريغ البيانات إلى القرص، أو إعادة التقسيم، أو تبديل
الاستراتيجية — راجع
join_algorithm.
القيم الممكنة:
THROW— يطرح ClickHouse استثناءً ويوقف الاستعلام.BREAK— يوقف ClickHouse الاستعلام ولا يطرح استثناءً.
THROW.
انظر أيضًا