> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> تمكّن فهارس التخطي ClickHouse من تجاوز قراءة أجزاء كبيرة من البيانات التي يُضمن عدم احتوائها على أي قيم مطابقة.

# فهم فهارس تخطي البيانات في ClickHouse

export const Image = ({img, alt, size = "lg"}) => {
  const normalizedSize = ["sm", "md", "lg"].includes(size) ? size : "lg";
  return <div className={`ch-image-${normalizedSize}`}>
      <Frame>
        <img src={img} alt={alt} />
      </Frame>
    </div>;
};

<div id="introduction">
  ## مقدمة
</div>

تؤثر عوامل عديدة في أداء استعلامات ClickHouse. ويتمثل العامل الحاسم في معظم الحالات في ما إذا كان ClickHouse يستطيع استخدام المفتاح الأساسي عند تقييم شرط جملة WHERE في الاستعلام. لذلك، يُعد اختيار مفتاح أساسي يناسب أنماط الاستعلام الأكثر شيوعًا أمرًا أساسيًا لتصميم الجداول بفعالية.

ومع ذلك، مهما جرى ضبط المفتاح الأساسي بعناية، فستظل هناك حتمًا حالات استخدام لاستعلامات لا يمكنها الاستفادة منه بكفاءة. يعتمد المستخدمون عادةً على ClickHouse لبيانات السلاسل الزمنية، لكنهم كثيرًا ما يرغبون أيضًا في تحليل هذه البيانات نفسها وفق أبعاد أعمال أخرى، مثل معرّف العميل أو URL الموقع الإلكتروني أو رقم المنتج. في هذه الحالة، قد يتراجع أداء الاستعلامات بدرجة ملحوظة، لأن تطبيق شرط جملة WHERE قد يتطلب فحصًا كاملًا لكل قيمة في كل عمود. ومع أن ClickHouse يظل سريعًا نسبيًا حتى في هذه الظروف، فإن تقييم ملايين أو مليارات القيم الفردية يجعل الاستعلامات "غير المفهرسة" أبطأ بكثير في التنفيذ من الاستعلامات التي تستند إلى المفتاح الأساسي.

في قواعد البيانات العلائقية التقليدية، يتمثل أحد الأساليب لمعالجة هذه المشكلة في إضافة فهرس "ثانوي" واحد أو أكثر إلى جدول. وهذه بنية من نوع B-tree تتيح لقاعدة البيانات العثور على جميع الصفوف المطابقة على القرص في زمن O(log(n)) بدلًا من O(n) (أي فحص الجدول)، حيث تمثل n عدد الصفوف. لكن هذا النوع من الفهارس الثانوية لا يصلح مع ClickHouse (أو غيره من قواعد البيانات العمودية) لأنه لا توجد صفوف فردية على القرص يمكن إضافتها إلى الفهرس.

بدلًا من ذلك، يوفّر ClickHouse نوعًا مختلفًا من الفهارس يمكنه، في ظروف معينة، تحسين سرعة الاستعلامات بشكل كبير. وتُسمّى هذه البنى فهارس "التخطي" لأنها تمكّن ClickHouse من تخطي قراءة كتل كبيرة من البيانات المضمون أنها لا تحتوي على أي قيم مطابقة.

<div id="basic-operation">
  ## آلية العمل الأساسية
</div>

لا يمكنك استخدام فهارس تخطي البيانات إلا مع الجداول التابعة لعائلة MergeTree. ويتضمن كل فهرس تخطي البيانات أربع معلمات أساسية:

* اسم الفهرس. يُستخدم اسم الفهرس لإنشاء ملف الفهرس في كل قسم. كما يُطلب أيضًا كمعلمة عند حذف الفهرس أو تجسيده.
* تعبير الفهرس. يُستخدم تعبير الفهرس لحساب مجموعة القيم المخزنة في الفهرس. ويمكن أن يكون مزيجًا من الأعمدة والعوامل البسيطة و/أو مجموعة فرعية من الدوال التي يحددها نوع الفهرس.
* TYPE. يتحكم نوع الفهرس في الحساب الذي يحدد ما إذا كان من الممكن تخطي قراءة كل كتلة فهرس وتقييمها.
* GRANULARITY. تتكون كل كتلة مفهرسة من GRANULARITY من الحبيبات. على سبيل المثال، إذا كانت درجة تحبيب الفهرس الأساسي للجدول 8192 صفًا، وكانت درجة تحبيب الفهرس 4، فستتكون كل "كتلة" مفهرسة من 32768 صفًا.

عندما ينشئ المستخدم فهرس تخطي البيانات، سيكون هناك ملفان إضافيان في دليل كل جزء بيانات للجدول.

* `skp_idx_{index_name}.idx`، ويحتوي على قيم التعبير المرتبة
* `skp_idx_{index_name}.mrk2`، ويحتوي على الإزاحات المقابلة داخل ملفات أعمدة البيانات المرتبطة.

إذا تطابق جزء من شرط التصفية في جملة WHERE مع تعبير فهرس التخطي أثناء تنفيذ استعلام وقراءة ملفات الأعمدة ذات الصلة، فسيستخدم ClickHouse بيانات ملف الفهرس لتحديد ما إذا كان يجب معالجة كل كتلة بيانات ذات صلة أو يمكن تجاوزها (على افتراض أن الكتلة لم تكن قد استُبعدت بالفعل بتطبيق المفتاح الأساسي). ولاستخدام مثال مبسط جدًا، انظر إلى الجدول التالي المحمّل ببيانات يمكن التنبؤ بها.

```sql theme={null}
CREATE TABLE skip_table
(
  my_key UInt64,
  my_value UInt64
)
ENGINE MergeTree primary key my_key
SETTINGS index_granularity=8192;

INSERT INTO skip_table SELECT number, intDiv(number,4096) FROM numbers(100000000);
```

عند تنفيذ استعلام بسيط لا يستخدم `primary key`، يتم فحص جميع القيم المئة مليون في العمود `my_value`:

```sql theme={null}
SELECT * FROM skip_table WHERE my_value IN (125, 700)
```

```response theme={null}
┌─my_key─┬─my_value─┐
│ 512000 │      125 │
│ 512001 │      125 │
│    ... |      ... |
└────────┴──────────┘

8192 rows in set. Elapsed: 0.079 sec. Processed 100.00 million rows, 800.10 MB (1.26 billion rows/s., 10.10 GB/s.
```

أضِف الآن فهرسَ تخطٍّ بسيطًا جدًا:

```sql theme={null}
ALTER TABLE skip_table ADD INDEX vix my_value TYPE set(100) GRANULARITY 2;
```

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

لفهرسة البيانات الموجودة مسبقًا، استخدم هذه التعليمة:

```sql theme={null}
ALTER TABLE skip_table MATERIALIZE INDEX vix;
```

أعِد تنفيذ الاستعلام باستخدام الفهرس المُنشأ حديثًا:

```sql theme={null}
SELECT * FROM skip_table WHERE my_value IN (125, 700)
```

```response theme={null}
┌─my_key─┬─my_value─┐
│ 512000 │      125 │
│ 512001 │      125 │
│    ... |      ... |
└────────┴──────────┘

8192 rows in set. Elapsed: 0.051 sec. Processed 32.77 thousand rows, 360.45 KB (643.75 thousand rows/s., 7.08 MB/s.)
```

بدلًا من معالجة 100 مليون صف بحجم 800 ميغابايت، لم يقرأ ClickHouse ويحلّل سوى 32768 صفًا بحجم 360 كيلوبايت
\-- أي أربع حبيبات، يحتوي كلٌّ منها على 8192 صفًا.

وبصيغة أكثر وضوحًا، هكذا تمت قراءة 4096 صفًا ذات `my_value` يساوي 125 واختيارها، وكيف جرى
تخطي الصفوف التالية من دون القراءة من disk:

<Image img="https://mintcdn.com/private-7c7dfe99/NvnCM4vX9aZ07JxK/images/guides/best-practices/simple_skip.webp?fit=max&auto=format&n=NvnCM4vX9aZ07JxK&q=85&s=f4aa2703d9e4e94cae9d4007b0e033f6" size="md" alt="تخطي بسيط" width="1859" height="1618" data-path="images/guides/best-practices/simple_skip.webp" />

يمكنك الوصول إلى معلومات تفصيلية حول استخدام فهرس التخطي من خلال تمكين trace عند تنفيذ queries. من
clickhouse-client، اضبط `send_logs_level`:

```sql theme={null}
SET send_logs_level='trace';
```

سيوفر هذا معلومات مفيدة لاستكشاف الأخطاء وإصلاحها عند محاولة ضبط استعلامات SQL وفهارس الجدول.  ومن المثال
أعلاه، يُظهر سجل التصحيح أن فهرس التخطي استبعد جميع الحبيبات باستثناء اثنتين:

```sql theme={null}
<Debug> default.skip_table (933d4b2c-8cea-4bf9-8c93-c56e900eefd1) (SelectExecutor): Index `vix` has dropped 6102/6104 granules.
```

<div id="skip-index-types">
  ## أنواع فهارس التخطي
</div>

<div id="minmax">
  ### minmax
</div>

لا يتطلب هذا النوع من الفهارس خفيف الوزن أي معلمات. فهو يخزّن القيمتين الدنيا والعظمى لتعبير الفهرس
لكل كتلة (إذا كان التعبير عبارة عن tuple، فإنه يخزّن قيم كل عضو من عناصر
الـ tuple بشكل منفصل). ويُعد هذا النوع مثاليًا للأعمدة التي تميل إلى أن تكون مرتبة تقريبًا حسب القيمة. وعادةً ما يكون هذا النوع من الفهارس الأقل كلفةً عند تطبيقه أثناء معالجة الاستعلامات.

لا يعمل هذا النوع من الفهارس بشكل صحيح إلا مع تعبير scalar أو tuple -- ولن يُطبَّق الفهرس مطلقًا على التعبيرات التي تُرجع نوع بيانات array أو map.

<div id="set">
  ### set
</div>

يقبل نوع الفهرس خفيف الوزن هذا معاملًا واحدًا، وهو max\_size لمجموعة القيم في كل كتلة (وتسمح القيمة 0
بعدد غير محدود من القيم المميزة). تحتوي هذه المجموعة على جميع القيم في الكتلة (أو تكون فارغة إذا تجاوز عدد القيم قيمة max\_size). يعمل نوع الفهرس هذا جيدًا مع الأعمدة ذات الكاردينالية المنخفضة داخل كل مجموعة من الحبيبات (أي إنها، في الأساس، "متجمعة معًا") ولكن ذات كاردينالية أعلى بشكل عام.

تعتمد تكلفة هذا الفهرس وأداؤه وفعاليته على الكاردينالية داخل الكتل. إذا كانت كل كتلة تحتوي على عدد كبير من القيم الفريدة، فإما أن يكون تقييم شرط الاستعلام على مجموعة فهرس كبيرة مكلفًا جدًا، أو لن يُطبَّق الفهرس لأن الفهرس يكون فارغًا نتيجة تجاوز max\_size.

<div id="text">
  ### text
</div>

بالنسبة إلى أعباء العمل التي تتضمن البحث باللغة الطبيعية أو البحث في النصوص الحرة (مثل البحث عن كلمات أو عبارات في أعمدة نصية كبيرة)، يوفّر ClickHouse **فهرسًا نصيًا** (وهو فهرس مقلوب حقيقي).
يدعم الفهرس النصي دلالات **البحث النصي الكامل** بكفاءة وعمليات البحث عن الرموز المميّزة. وهو الخيار الموصى به لاستعلامات **البحث النصي الكامل** لأنه يوفّر فهرسة حتمية للرموز المميّزة وأداءً أفضل لوظائف البحث مثل `hasAnyToken` و`hasAllTokens`، كما يُحسّن أيضًا جميع وظائف البحث النصي الشائعة.

اطّلع على توثيق الفهرس النصي لمزيد من التفاصيل [هنا](/docs/ar/reference/engines/table-engines/mergetree-family/textindexes).

<div id="bloom-filter-types">
  ### أنواع Bloom filter
</div>

يُعد *Bloom filter* بنية بيانات تتيح اختبار الانتماء إلى مجموعة بكفاءة من حيث المساحة، مقابل احتمال طفيف لحدوث إيجابيات كاذبة. ولا تمثل الإيجابيات الكاذبة مشكلة كبيرة في حالة فهارس التخطي، لأن العيب الوحيد هو قراءة بعض الكتل غير الضرورية. ومع ذلك، فإن احتمال الإيجابيات الكاذبة يعني أنه ينبغي أن يكون من المتوقع أن يُقيَّم التعبير المفهرس إلى true، وإلا فقد يتم تخطي بيانات صحيحة.

ولأن Bloom filters أكثر كفاءة في التعامل مع اختبار عدد كبير من القيم المنفصلة، فقد تكون مناسبة للتعبيرات الشرطية التي تنتج عددًا أكبر من القيم المطلوب اختبارها. وعلى وجه الخصوص، يمكن تطبيق فهرس Bloom filter على المصفوفات، حيث تُختبر كل قيمة في المصفوفة، وكذلك على الخرائط، وذلك بتحويل المفاتيح أو القيم إلى مصفوفة باستخدام الدالة `mapKeys` أو `mapValues`.

توجد ثلاثة أنواع من فهارس تخطي البيانات تعتمد على Bloom filters:

* الفهرس الأساسي **bloom\_filter**، ويأخذ معاملًا اختياريًا واحدًا لمعدل "الإيجابيات الكاذبة" المسموح به بين 0 و1 (إذا لم يُحدَّد، تُستخدم القيمة .025).

* الفهرس المتخصص **tokenbf\_v1** *(مهمل)*. يأخذ ثلاثة معاملات، وكلها مرتبطة بضبط Bloom filter المستخدم: (1) حجم المرشح بالبايت (المرشحات الأكبر تقل فيها الإيجابيات الكاذبة، لكن على حساب قدر من مساحة التخزين)، و(2) عدد دوال hash المطبقة (ومرة أخرى، تؤدي زيادة دوال hash إلى تقليل الإيجابيات الكاذبة)، و(3) قيمة seed لدوال hash الخاصة بـ Bloom filter. راجع الحاسبة [هنا](https://hur.st/bloomfilter/) لمزيد من التفاصيل حول كيفية تأثير هذه المعاملات في عمل Bloom filter.
  يعمل هذا الفهرس فقط مع أنواع البيانات String وFixedString وMap. ويُقسَّم تعبير الإدخال إلى تسلسلات من المحارف تفصل بينها محارف غير أبجدية رقمية. على سبيل المثال، ستحتوي قيمة العمود `This is a candidate for a "full text" search` على الرموز `This` `is` `a` `candidate` `for` `full` `text` `search`. وهو مخصص للاستخدام في عمليات البحث LIKE وEQUALS وIN وhasToken() وعمليات البحث المشابهة عن الكلمات والقيم الأخرى داخل السلاسل النصية الأطول. على سبيل المثال، قد يكون أحد الاستخدامات الممكنة هو البحث عن عدد صغير من أسماء الأصناف أو أرقام الأسطر في عمود يحتوي على أسطر سجلات تطبيقات حرة التنسيق.

* الفهرس المتخصص **ngrambf\_v1** *(مهمل)*. يعمل هذا الفهرس بالطريقة نفسها التي يعمل بها فهرس token. ويأخذ معاملًا إضافيًا واحدًا قبل إعدادات Bloom filter، وهو حجم ngrams المطلوب فهرستها. والـ ngram هي سلسلة محارف طولها `n` من أي محارف، لذا فإن السلسلة `A short string` مع حجم ngram مقداره 4 ستُفهرس على النحو التالي:
  ```text theme={null}
  'A sh', ' sho', 'shor', 'hort', 'ort ', 'rt s', 't st', ' str', 'stri', 'trin', 'ring'
  ```

يمكن أن يكون هذا الفهرس مفيدًا أيضًا في عمليات البحث النصي، ولا سيما في اللغات التي لا توجد فيها فواصل بين الكلمات، مثل الصينية.

> بالنسبة لأعباء عمل البحث النصي الكامل، يُوصى باستخدام **الفهرس النصي** المخصص (انظر [Text index for full-text search](/docs/ar/reference/engines/table-engines/mergetree-family/textindexes)) بدلًا من الفهرسين المهملين *tokenbf\_v1* أو *ngrambf\_v1*.
> يوفر الفهرس النصي inverted index حقيقيًا مع أداء بحث أفضل، وسلوك أكثر قابلية للتنبؤ، ومرونة وأداء أعلى مقارنةً بفهارس Bloom filter المعتمدة على الرموز.

<div id="skip-index-functions">
  ## دوال فهارس التخطي
</div>

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

* عند إدراج البيانات ويُعرَّف الفهرس كتعبير دالي (مع تخزين ناتج التعبير في ملفات الفهرس)، أو
* عند معالجة الاستعلام ويُطبَّق التعبير على قيم الفهرس المخزنة لتحديد ما إذا كان ينبغي استبعاد كتلة.

يعمل كل نوع من فهارس التخطي على مجموعة فرعية من دوال ClickHouse المتاحة والملائمة لتنفيذ الفهرس، والمذكورة
[هنا](/docs/ar/reference/engines/table-engines/mergetree-family/mergetree#functions-support). وبوجه عام، فإن فهارس Set والفهارس المعتمدة على Bloom filter (وهو نوع آخر من فهارس Set) كلاهما غير مرتَّب، ولذلك لا يعملان مع النطاقات. وعلى النقيض من ذلك، تعمل فهارس MinMax بكفاءة عالية مع النطاقات لأن تحديد ما إذا كانت النطاقات تتقاطع سريع جدًا. وتعتمد فعالية دوال المطابقة الجزئية LIKE وstartsWith وendsWith وhasToken على نوع الفهرس المستخدم، وتعبير الفهرس، والبنية الفعلية للبيانات.

<div id="skip-index-settings">
  ## إعدادات فهارس التخطي
</div>

هناك إعدادان متاحان ينطبقان على فهارس التخطي.

* **use\_skip\_indexes**  (0 أو 1، والقيمة الافتراضية 1).  لا يمكن لجميع الاستعلامات استخدام فهارس التخطي بكفاءة.  إذا كان من المرجح أن يشمل شرط التصفية
  معظم الحبيبات، فإن تطبيق فهرس تخطي البيانات يفرض تكلفة غير ضرورية، وقد تكون كبيرة أحيانًا.  اضبط القيمة على
  0 للاستعلامات التي لا يُتوقع أن تستفيد من أي من فهارس التخطي.
* **force\_data\_skipping\_indices** (قائمة بأسماء الفهارس مفصولة بفواصل).  يمكن استخدام هذا الإعداد لمنع بعض أنواع الاستعلامات
  غير الفعّالة.  في الحالات التي يكون فيها الاستعلام عن جدول مكلفًا جدًا ما لم يُستخدم فهرس تخطٍ، فإن استخدام هذا الإعداد مع اسم فهرس واحد أو أكثر
  سيؤدي إلى إرجاع استثناء لأي استعلام لا يستخدم أيًا من الفهارس المُدرجة.  وهذا من شأنه أن يمنع الاستعلامات
  المكتوبة بشكل سيئ من استهلاك موارد الخادم.

<div id="skip-best-practices">
  ## أفضل ممارسات فهارس التخطي
</div>

فهارس التخطي ليست بديهية، خاصةً لمن اعتادوا على الفهارس الثانوية المعتمدة على الصفوف في عالم RDMS أو الفهارس المقلوبة في مخازن المستندات. ولتحقيق أي فائدة منها، يجب أن يجنّب تطبيق فهرس تخطي البيانات في ClickHouse عددًا كافيًا من قراءات الحبيبات بما يعوّض تكلفة حساب الفهرس. والأهم من ذلك، إذا ظهرت قيمة ما ولو مرة واحدة داخل كتلة مفهرسة، فهذا يعني أنه يجب قراءة الكتلة كاملةً إلى الذاكرة وفحصها، وبذلك تكون تكلفة الفهرس قد تكبّدتها بلا داعٍ.

ضع في اعتبارك توزيع البيانات التالي:

<Image img="https://mintcdn.com/private-7c7dfe99/NvnCM4vX9aZ07JxK/images/guides/best-practices/bad_skip.webp?fit=max&auto=format&n=NvnCM4vX9aZ07JxK&q=85&s=de9cae80a4056483dc3c1e07d56f7dbc" size="md" alt="تخطٍّ سيئ" width="2269" height="1616" data-path="images/guides/best-practices/bad_skip.webp" />

افترض أن المفتاح الأساسي/مفتاح ORDER BY هو `timestamp`، وأن هناك فهرسًا على `visitor_id`. انظر الاستعلام التالي:

```sql theme={null}
SELECT timestamp, url FROM table WHERE visitor_id = 1001`
```

سيكون الفهرس الثانوي التقليدي مفيدًا للغاية مع هذا النوع من توزيع البيانات. فبدلًا من قراءة الصفوف الـ32768 كلها للعثور على
الصفوف الخمسة التي تحتوي على `visitor_id` المطلوب، سيضم الفهرس الثانوي خمسة مواضع صفوف فقط، ولن تُقرأ من القرص إلا هذه الصفوف الخمسة
فحسب. أما في ClickHouse فالأمر مع فهرس تخطي البيانات معاكس تمامًا. إذ ستُفحص جميع القيم الـ32768 في العمود `visitor_id`
بغض النظر عن نوع فهرس التخطي.

وبناءً على ذلك، فإن الميل الطبيعي لمحاولة تسريع استعلامات ClickHouse بمجرد إضافة فهرس إلى
أعمدة المفتاح يكون غالبًا في غير محلّه. ولا ينبغي استخدام هذه الإمكانية المتقدمة إلا بعد دراسة بدائل أخرى، مثل تعديل المفتاح الأساسي (راجع [How to Pick a Primary Key](/docs/ar/guides/clickhouse/data-modelling/sparse-primary-indexes))، أو استخدام projections، أو استخدام العروض المادية. وحتى عندما يكون فهرس تخطي البيانات مناسبًا، فإن الضبط الدقيق لكلٍ من الفهرس والجدول
يكون ضروريًا في كثير من الأحيان.

في معظم الحالات، يتطلب فهرس التخطي المفيد وجود ارتباط قوي بين المفتاح الأساسي والعمود/التعبير غير الأساسي المستهدف.
فإذا لم يوجد هذا الارتباط (كما في المخطط أعلاه)، فستكون احتمالية أن يستوفي شرط التصفية صف واحد على الأقل من الصفوف الموجودة في
الكتلة التي تضم عدة آلاف من القيم مرتفعة، ولن يُتخطى سوى عدد قليل من الكتل. وعلى النقيض من ذلك، إذا كان نطاق من قيم المفتاح الأساسي (مثل وقت
اليوم) مرتبطًا بقوة بالقيم الموجودة في العمود المرشح للفهرسة (مثل أعمار مشاهدي التلفاز)، فمن المرجح أن يكون الفهرس من نوع minmax
مفيدًا. ولاحظ أنه قد يكون من الممكن زيادة هذا الارتباط عند إدراج البيانات، إما عبر تضمين
أعمدة إضافية في مفتاح الفرز/ORDER BY، أو عبر تجميع عمليات الإدراج بطريقة تجعل القيم المرتبطة بالمفتاح الأساسي مجمّعة عند الإدراج. فعلى
سبيل المثال، يمكن تجميع جميع الأحداث الخاصة بـ`site_id` معيّن وإدراجها معًا بواسطة عملية الاستيعاب، حتى لو كان المفتاح الأساسي
عبارة عن timestamp يحتوي على أحداث من عدد كبير من المواقع. وسيؤدي ذلك إلى تكوين كثير من الحبيبات التي لا تحتوي إلا على عدد قليل من معرّفات المواقع، بحيث يمكن
تخطي كثير من الكتل عند البحث باستخدام قيمة `site_id` محددة.

ومن المرشحين الجيدين الآخرين لفهرس التخطي التعبيرات ذات الكاردينالية العالية حيث تكون أي قيمة واحدة متناثرة نسبيًا في البيانات. ومن الأمثلة
على ذلك منصة observability تتعقب رموز الخطأ في طلبات API. فبعض رموز الخطأ، رغم ندرتها في البيانات، قد تكون
مهمة للغاية لعمليات البحث. إذ يتيح فهرس تخطي من نوع set على العمود `error_code` تجاوز الغالبية العظمى من الكتل التي لا تحتوي على
أخطاء، ومن ثم تحسين الاستعلامات التي تركز على الأخطاء تحسينًا كبيرًا.

وأخيرًا، فإن أفضل ممارسة أساسية هي: اختبر، ثم اختبر، ثم اختبر. ومرة أخرى، وعلى خلاف فهارس b-tree الثانوية أو الفهارس المقلوبة المستخدمة في البحث داخل المستندات،
فإن سلوك فهرس تخطي البيانات ليس سهل التنبؤ. فإضافته إلى جدول تترتب عليها تكلفة ملموسة سواء عند استيعاب البيانات أو عند تنفيذ الاستعلامات
التي لا تستفيد من الفهرس لأي سبب من الأسباب. لذا ينبغي دائمًا اختباره على بيانات من النوع المستخدم في العالم الحقيقي، كما ينبغي أن يشمل الاختبار
اختلافات في النوع، وحجم granularity، وغيرها من المعلمات. وغالبًا ما يكشف الاختبار عن أنماط ومزالق لا تكون واضحة
من خلال التجارب الذهنية وحدها.

<div id="related-docs">
  ## وثائق ذات صلة
</div>

* [دليل أفضل الممارسات](/docs/ar/concepts/best-practices/using-data-skipping-indices)
* [أمثلة على فهرس تخطي البيانات](/docs/ar/concepts/features/performance/skip-indexes/skipping-indexes-examples)
* [إدارة فهارس تخطي البيانات](/docs/ar/reference/statements/alter/skipping-index)
* [معلومات جدول النظام](/docs/ar/reference/system-tables/data_skipping_indices)
