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

> توثيق لعبارة PREWHERE

# عبارة PREWHERE

يمكن أن تجعل `PREWHERE` التصفية أكثر كفاءة من خلال تقليل كمية البيانات المقروءة. افتراضيًا، يطبّق ClickHouse هذا التحسين حتى عندما لا يحدد الاستعلام `PREWHERE` صراحةً، وذلك بنقل الشروط المؤهلة من [`WHERE`](/ar/reference/statements/select/where) إلى `PREWHERE`. يمكنك تحديد `PREWHERE` صراحةً للتحكم في الشروط التي تُطبّق في هذه المرحلة.

باستخدام `PREWHERE`، يقرأ ClickHouse أولًا الأعمدة اللازمة لتقييم الشرط فقط. ثم يقرأ الأعمدة الأخرى التي يتطلبها الاستعلام للكتل التي تحتوي على صف مطابق واحد على الأقل فقط. يمكن أن يقلل ذلك من كمية البيانات المقروءة عندما يستخدم الشرط أعمدة أقل من بقية الاستعلام ويستبعد عددًا كبيرًا من الكتل.

<div id="controlling-prewhere-manually">
  ## التحكّم اليدوي في `PREWHERE`
</div>

حدّد `PREWHERE` يدويًا عندما يشير الشرط إلى عدد قليل من الأعمدة ويستبعد عددًا كبيرًا من الصفوف. يمكن أن يقلل ذلك من كمية البيانات المقروءة للأعمدة المتبقية.

يمكن أن يحتوي الاستعلام على كلٍّ من `PREWHERE` و`WHERE`. في هذه الحالة، يُقيَّم `PREWHERE` أولًا.

اضبط [`optimize_move_to_prewhere`](/ar/reference/settings/session-settings/optimize-move-to-prewhere#optimize_move_to_prewhere) على `0` لمنع ClickHouse من نقل الشروط تلقائيًا من `WHERE` إلى `PREWHERE`.

بالنسبة إلى الاستعلامات التي تستخدم المعدِّل [`FINAL`](/ar/reference/statements/select/from#final-modifier)، لا ينقل ClickHouse الشروط من `WHERE` إلى `PREWHERE` إلا إذا كان كلٌّ من [`optimize_move_to_prewhere`](/ar/reference/settings/session-settings/optimize-move-to-prewhere#optimize_move_to_prewhere) و[`optimize_move_to_prewhere_if_final`](/ar/reference/settings/session-settings/optimize-move-to-prewhere#optimize_move_to_prewhere_if_final) مفعّلًا.

<Note>
  افتراضيًا، يُقيَّم `PREWHERE` قبل `FINAL`، لذا قد تُنتج استعلامات `FROM ... FINAL` نتائج غير متوقعة عندما يشير `PREWHERE` إلى أعمدة لا تدخل ضمن مفتاح `ORDER BY` للجدول.
</Note>

<div id="prewhere-with-join">
  ## `PREWHERE` مع `JOIN`
</div>

يمكن لشرط `PREWHERE` في استعلام يتضمن [`JOIN`](/ar/reference/statements/select/join) أن يشير مباشرةً إلى أعمدة جدول واحد كحد أقصى. يطبّق ClickHouse الشرط على صفوف ذلك الجدول قبل وصولها إلى عملية الربط.

في المقابل، يرشّح شرط `WHERE` منطقيًا نتيجة الربط، رغم أن المُحسِّن قد يطبّقه قبل عملية الربط إذا كان ذلك لا يغيّر النتيجة. لذلك، قد يؤدي استخدام الشرط نفسه في `PREWHERE` و`WHERE` إلى نتائج مختلفة، لا سيما مع عمليات الربط الخارجية.

ينشئ المثال التالي جدولين لتوضيح هذا الاختلاف:

```sql theme={null}
CREATE TABLE table_1
(
    `id` UInt32,
    `value` String
)
ENGINE = MergeTree
ORDER BY id;

CREATE TABLE table_2
(
    `id` UInt32,
    `value` String
)
ENGINE = MergeTree
ORDER BY id;

INSERT INTO table_1 VALUES (1, 'a'), (2, 'b'), (3, 'c');
INSERT INTO table_2 VALUES (1, 'x'), (2, 'y'), (3, 'z');
```

في الاستعلام الأول، يُطبّق `PREWHERE` التصفية على `table_2` قبل `LEFT JOIN`، لذلك يبقى الصف في `table_1` الذي له `id = 1` دون مطابقة:

```sql theme={null}
SELECT
    table_1.id,
    table_1.value,
    table_2.value
FROM table_1
LEFT JOIN table_2 ON table_1.id = table_2.id
PREWHERE table_2.id >= 2
ORDER BY table_1.id;
```

```text theme={null}
   ┌─id─┬─value─┬─table_2.value─┐
1. │  1 │ a     │               │
2. │  2 │ b     │ y             │
3. │  3 │ c     │ z             │
   └────┴───────┴───────────────┘
```

يؤدي استخدام الشرط نفسه في `WHERE` إلى تصفية نتيجة الربط، مما يستبعد الصف الذي فيه `id = 1`:

```sql theme={null}
SELECT
    table_1.id,
    table_1.value,
    table_2.value
FROM table_1
LEFT JOIN table_2 ON table_1.id = table_2.id
WHERE table_2.id >= 2
ORDER BY table_1.id;
```

```text theme={null}
   ┌─id─┬─value─┬─table_2.value─┐
1. │  2 │ b     │ y             │
2. │  3 │ c     │ z             │
   └────┴───────┴───────────────┘
```

<div id="limitations">
  ## القيود
</div>

لا تكون `PREWHERE` مدعومة إلا في الجداول التابعة لعائلة [\*MergeTree](/ar/reference/engines/table-engines/mergetree-family/index).

<div id="example">
  ## مثال
</div>

```sql theme={null}
CREATE TABLE mydata
(
    `A` Int64,
    `B` Int8,
    `C` String
)
ENGINE = MergeTree
ORDER BY A AS
SELECT
    number,
    0,
    if(number between 1000 and 2000, 'x', toString(number))
FROM numbers(10000000);

SELECT count()
FROM mydata
WHERE (B = 0) AND (C = 'x');

1 row in set. Elapsed: 0.074 sec. Processed 10.00 million rows, 168.89 MB (134.98 million rows/s., 2.28 GB/s.)

-- Enable tracing to see which predicates are moved to PREWHERE.
set send_logs_level='debug';

MergeTreeWhereOptimizer: condition "B = 0" moved to PREWHERE  
-- ClickHouse automatically moves B = 0 to PREWHERE, but this condition does not filter any rows because B is always 0.

-- Move the more selective C = 'x' predicate to PREWHERE.

SELECT count()
FROM mydata
PREWHERE C = 'x'
WHERE B = 0;

1 row in set. Elapsed: 0.069 sec. Processed 10.00 million rows, 158.89 MB (144.90 million rows/s., 2.30 GB/s.)

-- The query with manually specified PREWHERE processes slightly less data: 158.89 MB instead of 168.89 MB.
```
