معالجة الاستعلام بدون تحسين PREWHERE
① يتضمن الاستعلام عامل تصفية على العمود
town، وهو جزء من المفتاح الأساسي للجدول، وبالتالي فهو أيضًا جزء من الفهرس الأساسي.
② لتسريع الاستعلام، يحمّل ClickHouse الفهرس الأساسي للجدول إلى الذاكرة.
③ يفحص ClickHouse إدخالات الفهرس لتحديد الحبيبات في العمود town التي قد تحتوي على صفوف تطابق الشرط.
④ تُحمَّل هذه الحبيبات التي يُحتمل أن تكون ذات صلة إلى الذاكرة، إلى جانب الحبيبات المتوافقة موضعيًا من أي أعمدة أخرى يحتاج إليها الاستعلام.
⑤ ثم تُطبَّق عوامل التصفية المتبقية أثناء تنفيذ الاستعلام.
كما ترى، من دون PREWHERE، تُحمَّل جميع الأعمدة التي يُحتمل أن تكون ذات صلة قبل التصفية، حتى إن كان عدد قليل فقط من الصفوف يطابق فعليًا.
كيف يحسّن PREWHERE كفاءة الاستعلام
① يتضمن الاستعلام عامل تصفية على العمود
town، وهو جزء من المفتاح الأساسي للجدول، وبالتالي فهو أيضًا جزء من الفهرس الأساسي.
② وكما في التشغيل من دون عبارة PREWHERE، يحمّل ClickHouse الفهرس الأساسي إلى الذاكرة لتسريع الاستعلام،
③ ثم يفحص إدخالات الفهرس لتحديد أي الحبيبات من العمود town قد تحتوي على صفوف تطابق شرط التصفية.
أما الآن، وبفضل عبارة PREWHERE، فتختلف الخطوة التالية: فبدلًا من قراءة جميع الأعمدة ذات الصلة مسبقًا، يصفّي ClickHouse البيانات عمودًا بعمود، ولا يحمّل إلا ما يلزم فعلًا. ويؤدي ذلك إلى تقليل عمليات الإدخال/الإخراج بشكل كبير، خاصةً في الجداول العريضة.
ومع كل خطوة، لا يحمّل إلا الحبيبات التي تحتوي على صف واحد على الأقل اجتاز — أي طابق — عامل التصفية السابق. ونتيجة لذلك، يتناقص عدد الحبيبات التي يجب تحميلها وتقييمها لكل عامل تصفية بشكل مستمر:
الخطوة 1: التصفية حسب المدينةيبدأ ClickHouse معالجة PREWHERE بقراءة ① الحبيبات المحددة من العمود
town والتحقق من أيّها يحتوي فعليًا على صفوف تطابق London.
في مثالنا، تتطابق جميع الحبيبات المحددة، لذا ② تُحدَّد بعد ذلك الحبيبات المناظرة موضعيًا لعمود التصفية التالي — date — للمعالجة:
الخطوة 2: التصفية حسب التاريخ
بعد ذلك، يقرأ ClickHouse ① الحبيبات المحددة من العمود
date لتقييم عامل التصفية date > '2024-12-31'.
في هذه الحالة، تحتوي حبيبتان من أصل ثلاث على صفوف متطابقة، لذا ② لا تُحدَّد لمزيد من المعالجة إلا الحبيبات المناظرة موضعيًا لهما من عمود التصفية التالي — price —:
الخطوة 3: التصفية حسب السعر
أخيرًا، يقرأ ClickHouse ① الحبيبتين المحددتين من العمود
price لتقييم عامل التصفية الأخير price > 10_000.
ولا تحتوي على صفوف متطابقة سوى واحدة من الحبيبتين، لذا ② لا يلزم تحميل سوى الحبيبة المناظرة موضعيًا لها من عمود SELECT — street — لمزيد من المعالجة:
بحلول الخطوة الأخيرة، لا يُحمَّل سوى الحد الأدنى من حبيبات الأعمدة، أي تلك التي تحتوي على صفوف متطابقة. ويؤدي ذلك إلى خفض استخدام الذاكرة، وتقليل عمليات الإدخال/الإخراج على القرص، وتسريع تنفيذ الاستعلام.
يقلّل PREWHERE كمية البيانات المقروءة، لا عدد الصفوف المُعالَجةلاحظ أن ClickHouse يعالج العدد نفسه من الصفوف في نسختَي الاستعلام، مع PREWHERE وبدونه. ومع ذلك، عند تطبيق تحسينات PREWHERE، لا يلزم تحميل جميع قيم الأعمدة لكل صف مُعالَج.
يُطبَّق تحسين PREWHERE تلقائيًا
optimize_move_to_prewhere مُمكّنًا (true افتراضيًا)، ينقل ClickHouse شروط التصفية تلقائيًا من WHERE إلى PREWHERE، مع إعطاء الأولوية للشروط التي تقلّل حجم البيانات المقروءة بأكبر قدر.
الفكرة هنا هي أن فحص الأعمدة الأصغر يكون أسرع، وبحلول وقت معالجة الأعمدة الأكبر، تكون معظم الحبيبات قد استُبعدت بالفعل عبر التصفية. ونظرًا لأن جميع الأعمدة تحتوي على العدد نفسه من الصفوف، فإن حجم العمود يتحدد أساسًا وفق نوع البيانات؛ فعلى سبيل المثال، يكون عمود UInt8 أصغر بكثير عادةً من عمود String.
يتبع ClickHouse هذه الاستراتيجية افتراضيًا بدءًا من الإصدار 23.2، إذ يرتّب أعمدة التصفية في PREWHERE للمعالجة متعددة الخطوات ترتيبًا تصاعديًا حسب الحجم غير المضغوط.
واعتبارًا من الإصدار 23.11، يمكن لإحصاءات الأعمدة الاختيارية تحسين ذلك بدرجة أكبر من خلال اختيار ترتيب معالجة التصفية استنادًا إلى انتقائية البيانات الفعلية، لا إلى حجم العمود فحسب.
كيفية قياس تأثير PREWHERE
optimize_move_to_prewhere setting وبدونه.
نبدأ بتشغيل الاستعلام مع تعطيل الإعداد optimize_move_to_prewhere:
optimize_move_to_prewhere. (لاحظ أن هذا الإعداد اختياري، إذ يكون مفعّلًا افتراضيًا):
أهم النقاط
- يتجنب PREWHERE قراءة بيانات الأعمدة التي ستُستبعَد لاحقًا بالتصفية، مما يوفر موارد الإدخال/الإخراج والذاكرة.
- يعمل تلقائيًا عند تفعيل
optimize_move_to_prewhere(وهو الإعداد الافتراضي). - ترتيب التصفية مهم: ينبغي أن تأتي الأعمدة الصغيرة والانتقائية أولًا.
- استخدم
EXPLAINوالسجلات للتحقق من تطبيق PREWHERE وفهم تأثيره. - يكون PREWHERE أكثر تأثيرًا مع الجداول العريضة وعمليات المسح الكبيرة ذات عوامل التصفية الانتقائية.