> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-detect-table-modification.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# إعدادات الجلسة join_*

> إعدادات جلسة ClickHouse ضمن مجموعة join_* المُولَّدة.

export const VersionHistory = ({rows = []}) => {
  if (rows.length === 0) {
    return null;
  }
  const headers = ["الإصدار", "القيمة الافتراضية", "التعليق"];
  const border = "1px solid rgba(128, 128, 128, 0.3)";
  const cell = {
    border,
    padding: "0.25rem 0.5rem",
    textAlign: "start",
    verticalAlign: "top"
  };
  return <details className="not-prose" style={{
    border,
    borderRadius: "0.5rem",
    margin: "0.5rem 0",
    padding: "0.5rem 0.75rem",
    fontSize: "0.8125rem",
    lineHeight: "1.125rem"
  }}>
      <summary style={{
    cursor: "pointer",
    fontWeight: 600,
    opacity: 0.72
  }}>
        سجل الإصدارات
      </summary>
      <table style={{
    borderCollapse: "collapse",
    width: "100%",
    margin: "0.5rem 0 0"
  }}>
        <thead>
          <tr>
            {headers.map(header => <th key={header} style={{
    ...cell,
    fontWeight: 600,
    opacity: 0.72
  }}>
                {header}
              </th>)}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, row_index) => <tr key={row.id ?? row_index}>
              {(row.items ?? []).map((item, item_index) => <td key={item_index} style={{
    ...cell,
    overflowWrap: "anywhere"
  }}>
                  {item?.label}
                </td>)}
            </tr>)}
        </tbody>
      </table>
    </details>;
};

export const SettingsInfoBlock = ({type, default_value, changeable_without_restart}) => {
  return <div className="not-prose" style={{
    display: "flex",
    flexWrap: "wrap",
    alignItems: "baseline",
    columnGap: "0.5rem",
    rowGap: "0.125rem",
    margin: "0.375rem 0",
    fontSize: "0.8125rem",
    lineHeight: "1.125rem"
  }}>
      <div style={{
    fontWeight: 600,
    opacity: 0.72
  }}>النوع</div>
      <div style={{
    overflowWrap: "anywhere"
  }}>{type}</div>
      <div style={{
    fontWeight: 600,
    opacity: 0.72,
    marginInlineStart: "0.5rem"
  }}>القيمة الافتراضية</div>
      <div style={{
    overflowWrap: "anywhere"
  }}>{default_value}</div>
      {changeable_without_restart && <div style={{
    fontWeight: 600,
    opacity: 0.72,
    marginInlineStart: "0.5rem"
  }}>
          يمكن تغييره دون إعادة التشغيل
        </div>}
      {changeable_without_restart && <div style={{
    overflowWrap: "anywhere"
  }}>
          {changeable_without_restart}
        </div>}
    </div>;
};

هذه الإعدادات متوفرة في [system.settings](/ar/reference/system-tables/settings)، وهي مُولَّدة تلقائيًا من [الملف المصدر](https://github.com/ClickHouse/ClickHouse/blob/master/src/Core/Settings.cpp).

<div id="join_algorithm">
  ## join\_algorithm
</div>

<SettingsInfoBlock type="JoinAlgorithm" default_value="direct,parallel_hash,hash" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "24.12"},{"label": "direct,parallel_hash,hash"},{"label": "تم إهمال 'default' لصالح تحديد خوارزميات join صراحةً، كما أصبحت parallel_hash الآن مفضلة على hash"}]}]} />

يحدد خوارزمية [JOIN](/ar/reference/statements/select/join) المستخدمة.

يمكن تحديد عدة خوارزميات، وتُختار الخوارزمية المناسبة لكل استعلام بحسب kind/الصرامة ومحرك الجدول.

تؤثر معظم الخوارزميات في الاستعلام فقط عندما تكون هي الخوارزمية المحددة له. لكن بعضها يغيّر التخطيط بمجرد إدراجه، حتى لو كان خيارًا احتياطيًا منخفض الأولوية لا يُختار في النهاية، لأن القرار يُتخذ قبل اختيار الخوارزمية. ويوجد تأثيران من هذا النوع:

* يصبح استدلال النوع لـ 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](https://en.wikipedia.org/wiki/Hash_join#Grace_hash_join). توفّر Grace hash خيار خوارزمية يتيح تنفيذ joins معقدة بكفاءة مع الحد من استهلاك الذاكرة.

في المرحلة الأولى من grace join، يُقرأ الجدول الأيمن ويُقسَّم إلى N من الـ buckets وفقًا لقيمة hash الخاصة بـ key columns (في البداية تكون N هي `grace_hash_join_initial_buckets`). ويُنفَّذ ذلك بطريقة تضمن إمكانية معالجة كل bucket بشكل مستقل. تُضاف rows من الـ bucket الأولى إلى hash table داخل الذاكرة، بينما تُحفَظ البقية على disk. وإذا تجاوز نمو hash table مقدار memory limit (على سبيل المثال كما هو محدد بواسطة [`max_bytes_in_join`](/ar/reference/settings/session-settings/max-bytes#max_bytes_in_join))، فسيُزاد عدد الـ buckets ويُعاد تحديد الـ bucket المخصصة لكل row. وأي rows لا تنتمي إلى الـ bucket الحالية تُفرَّغ وتُعاد إعادة تخصيصها.

يدعم `INNER/LEFT/RIGHT/FULL ALL/ANY JOIN`.

* hash

تُستخدم [Hash join algorithm](https://en.wikipedia.org/wiki/Hash_join). وهي أكثر تطبيقات join عمومية، إذ تدعم جميع التركيبات من kind وstrictness، كما تدعم عدة join keys مدمجة باستخدام `OR` في قسم `JOIN ON`.

عند استخدام خوارزمية `hash`، يُحمَّل الجزء الأيمن من `JOIN` إلى RAM.

* parallel\_hash

نوع مختلف من join `hash` يقسّم البيانات إلى buckets ويبني عدة hash tables بدلًا من واحدة، بالتوازي، لتسريع هذه العملية.

عند استخدام خوارزمية `parallel_hash`، يُحمَّل الجزء الأيمن من `JOIN` إلى RAM.

* partial\_merge

نوع مختلف من [sort-merge algorithm](https://en.wikipedia.org/wiki/Sort-merge_join)، حيث يُفرَز الجدول الأيمن بالكامل فقط.

لا يُدعَم `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](/ar/reference/engines/table-engines/special/dictionary) و[EmbeddedRocksDB](/ar/reference/engines/table-engines/integrations/embedded-rocksdb) وtables من نوع [MergeTree](/ar/reference/engines/table-engines/mergetree-family/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

[Sort-merge algorithm](https://en.wikipedia.org/wiki/Sort-merge_join) مع فرز كامل للجداول الموصولة قبل تنفيذ join.

* ie\_join

خوارزمية [IEJoin](https://vldb.org/pvldb/vol8/p2074-khayyat.pdf) المعتمدة على الفرز، والمخصصة لـ `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`](/ar/reference/settings/session-settings/max-rows#max_rows_in_join) و[`max_bytes_in_join`](/ar/reference/settings/session-settings/max-bytes#max_bytes_in_join) إجمالي الإدخال المتراكم لكلا الجانبين معًا (وليس الجانب الأيمن فقط)، ويُحدَّد الإجراء عند overflow بواسطة [`join_overflow_mode`](/ar/reference/settings/session-settings/join#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.

لا يؤدي تخطي ذلك إلا إلى تعطيل إعادة الكتابة هذه، وليس التوازي عمومًا: إذ تعمل join بوصفها `full_sorting_merge` واحدة، ولا يزال بإمكان جوانب MergeTree المقروءة بالترتيب أن تُقسَّم إلى shards عند المصدر بحسب primary-key ranges (التي ترتب بالمقارنة نفسها التي تستخدمها join، لذا تبقى المفاتيح المتساوية معًا) عند تمكين `query_plan_join_shard_by_pk_ranges`.

* prefer\_partial\_merge

يحاول ClickHouse دائمًا استخدام join `partial_merge` إن أمكن، وإلا يستخدم `hash`. *Deprecated*، وهو مماثل لـ `partial_merge,hash`.

* default (مهمل)

قيمة قديمة، يُرجى عدم استخدامها بعد الآن.
تماثل `direct,hash`، أي جرّب استخدام direct join وhash join (بهذا الترتيب).

<div id="join_any_take_last_row">
  ## join\_any\_take\_last\_row
</div>

<SettingsInfoBlock type="Bool" default_value="0" />

يغيّر سلوك عمليات JOIN ذات الصرامة `ANY` عندما يحتوي الجدول الأيمن على أكثر من صف مطابق واحد للمفتاح.

<Note>
  ينطبق هذا الإعداد على جداول محرك [`Join`](/ar/reference/engines/table-engines/special/join) وخوارزميات JOIN المعتمدة على hash.

  إذا تم إنشاء JOIN بالتوازي، فقد يصبح ترتيب الصفوف غير حتمي. وهذا يعني أن `join_any_take_last_row = 1` قد يعيد صفًا غير حتمي في استعلامات `ANY JOIN`.
</Note>

القيم الممكنة:

* 0 — إذا كان الجدول الأيمن يحتوي على أكثر من صف مطابق واحد، فلن يُضم إلا أول صف يتم العثور عليه.
* 1 — إذا كان الجدول الأيمن يحتوي على أكثر من صف مطابق واحد، فلن يُضم إلا آخر صف يتم العثور عليه.

انظر أيضًا:

* [عبارة JOIN](/ar/reference/statements/select/join)
* [محرك الجدول Join](/ar/reference/engines/table-engines/special/join)
* [join\_default\_strictness](/ar/reference/settings/session-settings/join#join_default_strictness)

<div id="join_default_strictness">
  ## join\_default\_strictness
</div>

<SettingsInfoBlock type="JoinStrictness" default_value="ALL" />

يضبط درجة الصرامة الافتراضية لعبارات [JOIN](/ar/reference/statements/select/join).

القيم الممكنة:

* `ALL` — إذا كان الجدول الأيمن يحتوي على عدة صفوف متطابقة، ينشئ ClickHouse [حاصلًا كارتيسيًا](https://en.wikipedia.org/wiki/Cartesian_product) من الصفوف المتطابقة. وهذا هو سلوك `JOIN` المعتاد في standard SQL.
* `ANY` — إذا كان الجدول الأيمن يحتوي على عدة صفوف متطابقة، فلا يُضم سوى أول صف يُعثر عليه. وإذا كان الجدول الأيمن يحتوي على صف متطابق واحد فقط، فستكون نتائج `ANY` و`ALL` متطابقة.
* `ASOF` — لربط التسلسلات ذات المطابقة غير المؤكدة.
* `Empty string` — إذا لم يتم تحديد `ALL` أو `ANY` في الاستعلام، يطرح ClickHouse استثناء.

<div id="join_on_disk_max_files_to_merge">
  ## join\_on\_disk\_max\_files\_to\_merge
</div>

<SettingsInfoBlock type="UInt64" default_value="64" />

يحدّ من عدد الملفات المسموح به للفرز المتوازي في عمليات MergeJoin عند تنفيذها على القرص.

كلما زادت قيمة الإعداد، زاد استخدام RAM وقلّت الحاجة إلى عمليات الإدخال/الإخراج على القرص.

القيم الممكنة:

* أي عدد صحيح موجب يبدأ من 2.

<div id="join_output_by_rowlist_perkey_rows_threshold">
  ## join\_output\_by\_rowlist\_perkey\_rows\_threshold
</div>

<SettingsInfoBlock type="UInt64" default_value="5" />

<VersionHistory rows={[{"id": "row-1","items": [{"label": "24.9"},{"label": "5"},{"label": "الحد الأدنى لمتوسط عدد الصفوف لكل مفتاح في الجدول الأيمن، لتحديد ما إذا كان سيتم إخراج النتائج وفق قائمة الصفوف في hash join."}]}]} />

الحد الأدنى لمتوسط عدد الصفوف لكل مفتاح في الجدول الأيمن، لتحديد ما إذا كان سيتم إخراج النتائج وفق قائمة الصفوف في hash join.

<div id="join_overflow_mode">
  ## join\_overflow\_mode
</div>

<SettingsInfoBlock type="OverflowMode" default_value="throw" />

يحدّد هذا الإعداد الإجراء الذي ينفّذه ClickHouse عندما تصل عملية join إلى أيٍّ من الحدود التالية:

* [max\_bytes\_in\_join](/ar/reference/settings/session-settings/max-bytes#max_bytes_in_join)
* [max\_rows\_in\_join](/ar/reference/settings/session-settings/max-rows#max_rows_in_join)

لا يُراعى هذا الإعداد إلا مع قيم [`join_algorithm`](/ar/reference/settings/session-settings/join#join_algorithm) `hash` و`parallel_hash` و`ie_join`.
أما الخوارزميات الأخرى (مثل `partial_merge` و`grace_hash` و`auto`) فتتعامل مع
هذه الحدود بطريقة مختلفة — مثل تفريغ البيانات إلى القرص، أو إعادة التقسيم، أو تبديل
الاستراتيجية — راجع
[`join_algorithm`](/ar/reference/settings/session-settings/join#join_algorithm).

القيم الممكنة:

* `THROW` — يطرح ClickHouse استثناءً ويوقف الاستعلام.
* `BREAK` — يوقف ClickHouse الاستعلام ولا يطرح استثناءً.

القيمة الافتراضية: `THROW`.

**انظر أيضًا**

* [عبارة JOIN](/ar/reference/statements/select/join)
* [محرك الجدول Join](/ar/reference/engines/table-engines/special/join)

<div id="join_use_nulls">
  ## join\_use\_nulls
</div>

<SettingsInfoBlock type="Bool" default_value="0" />

يحدّد هذا الإعداد سلوك [JOIN](/ar/reference/statements/select/join). عند دمج الجداول، قد تظهر خلايا فارغة. ويملؤها ClickHouse بطرق مختلفة وفقًا لهذا الإعداد.

Possible values:

* 0 — تُملأ الخلايا الفارغة بالقيمة الافتراضية لنوع الحقل المقابل.
* 1 — يتصرف `JOIN` بالطريقة نفسها كما في standard SQL. ويُحوَّل نوع الحقل المقابل إلى [Nullable](/ar/reference/data-types/nullable)، وتُملأ الخلايا الفارغة بـ [NULL](/ar/reference/syntax).
