Skip to main content
يصبح تحسين الاستعلام أسهل عند تغيير جزء واحد منه في كل مرة ومقارنة النتائج بخط أساس ثابت. يوضح هذا الدليل كيفية تبسيط الاستعلام تدريجيًا واستخدام الفروق بين عمليات التشغيل لتحديد العمليات الأكثر إسهامًا في مدة تنفيذه. يمكنك بعد ذلك التحقق من عنق الزجاجة المحتمل قبل اختيار التحسين المناسب.

قبل أن تبدأ

ابدأ بنمط متكرر من الاستعلامات البطيئة التي تريد التحقيق فيها. إذا لم تكن قد حددت نمطًا بعد، فراجع تشخيص الاستعلامات البطيئة للتعرّف على الخطوات. لتشغيل الأمثلة الواردة في هذا الدليل كما كُتبت، أنشئ الجدول nyc_taxi.trips_small_inferred وحمّله إذا لم تكن قد فعلت ذلك مسبقًا:
يبلغ حجم ملف Parquet المصدر نحو 5.8 GB. قد يستغرق تحميله عدة دقائق، حسب الشبكة والموارد المتاحة.
يستخدم الجدول النموذجي ORDER BY ()، لذا لا يمكن لفلتر التاريخ فيه استخدام مفتاح ترتيب لاستبعاد البيانات أثناء القراءة. استخدم المثال للتدرّب على منهجية المقارنة، لا باعتباره معيارًا للأداء.

آلية العمل

يتيح لك تبسيط الاستعلام تدريجيًا مقارنة مدته قبل إزالة إحدى مراحل المعالجة وبعدها. تساعدك الفروق على تحديد ما إذا كان ينبغي التحقيق في الفحص والتصفية والتجميع والحسابات التجميعية أو العمليات اللاحقة، مثل الفرز وتنسيق المخرجات:
  1. شغّل الاستعلام الأصلي لتحديد قياسات خط الأساس.
  2. احتفظ بـ GROUP BY، واستبدل الحسابات التجميعية في الاستعلام بـ count، وأزل العمليات اللاحقة، مثل الفرز وتنسيق المخرجات.
  3. أزل التجميع وشغّل count دون تجميع لتقدير مقدار العمل المتبقي من الفحص والتصفية وأي عمليات ربط.
تنطبق هذه المراحل مباشرةً على استعلامات التجميع التقليدية التي تستخدم التجميع حسب المجموعات. بالنسبة إلى الاستعلامات الأكثر تعقيدًا، طبّق المبدأ نفسه على كتلة SELECT واحدة في كل مرة: احتفظ بمصادر البيانات وعوامل التصفية المكافئة، وأزل عملية واحدة في كل مرة، وتحقّق من خطة التنفيذ بعد كل تغيير.
هذه الفروق تقديرات تشخيصية وليست قياسات دقيقة لمراحل تنفيذ ClickHouse. قد يؤدي تغيير الاستعلام إلى تغيير خطة تنفيذه، والأعمدة المقروءة، والبيانات المنقولة بين المراحل. استخدم النتائج لصياغة فرضية، ثم تحقّق منها باستخدام سجلات الاستعلامات وEXPLAIN.

وضع خط أساس قابل للتكرار

استخدم الممارسات التالية لجعل القياسات قابلة للمقارنة:
  • أبقِ عبارات FROM وJOIN وPREWHERE وWHERE دون تغيير، لضمان استخدام البيانات والنطاق الزمني نفسيهما في كل مقارنة.
  • شغّل كل إصدار من الاستعلام عدة مرات تحت حمل نظام مماثل.
  • حافظ على اتساق ظروف التخزين المؤقت. إما شغّل كل إصدار من الاستعلام قبل تسجيل القياسات، أو عطّل الذواكر المؤقتة المدرجة أدناه. لا تقارن بين عمليات التشغيل المخزنة مؤقتًا وغير المخزنة مؤقتًا.
  • سجّل مدةً ممثلة، مثل الوسيط لعمليات التشغيل المتكررة بعد أي عمليات إحماء، بدلًا من الاعتماد على أسرع نتيجة أو أبطئها.
  • غيّر متغيرًا واحدًا في كل مرة لكي تتمكن من ربط فرق الأداء بتغيير محدد.
لإجراء مقارنة تشخيصية دون استخدام التخزين المؤقت، عطّل ذاكرة ClickHouse المؤقتة لنظام الملفات للبيانات البعيدة، وذاكرة الاستعلام المؤقتة، وذاكرة التخزين المؤقت لشروط الاستعلام. عطّل الإسقاطات الضمنية أيضًا، حتى لا يستخدم count في التشغيل C خطة تنفيذ محسّنة تتجاوز الفحص الذي تنوي مقارنته.
تنطبق عبارات SET هذه على الجلسة الحالية فقط. نفّذ جميع استعلامات المقارنة ضمن هذه الجلسة، أو طبّق الإعدادات نفسها على كل عملية تشغيل. لا يؤدي إعداد ذاكرة التخزين المؤقت لنظام الملفات إلى تعطيل ذاكرة الصفحات المؤقتة في نظام التشغيل أو جميع ذواكر ClickHouse المؤقتة. عند الانتهاء، أغلق الجلسة المخصصة أو أعد كل إعداد إلى قيمته السابقة.
يجمع سير العمل بين عمليات تشغيل استعلامات مضبوطة وقياسات من سجل الاستعلامات: اجمع القياسات لكل عملية تشغيل كما يلي:
  1. عيّن معرّف استعلام فريدًا لكل عملية تشغيل، أو سجّل المعرّف الذي تنشئه واجهة الاستعلام. على سبيل المثال، سمِّ عمليات التشغيل المتكررة: bottleneck-a-1 وbottleneck-a-2 وbottleneck-a-3. عند استخدام clickhouse-client، مرّر --query_id your-query-id عند تنفيذ استعلام.
  2. نفّذ كل استعلام مقارنة عدة مرات في الظروف نفسها. افصل عمليات تشغيل الإحماء عن عمليات التشغيل المقاسة.
  3. أفرغ سجل الاستعلامات قبل البحث عن الاستعلامات المكتملة مؤخرًا:
    إذا لم تتمكن من تشغيل SYSTEM FLUSH LOGS، فانتظر حتى يُفرغ سجل الاستعلامات تلقائيًا، ثم أعد محاولة البحث. إذا لم يظهر السجل مطلقًا، فتحقق من تمكين تسجيل الاستعلامات، ومن قدرتك على قراءة system.query_log، ومن أنك تستعلم عن العقدة التي نفّذت الاستعلام.
  4. ابحث عن السجل المكتمل لكل معرّف استعلام. يسجل system.query_log حدثَي QueryStart وQueryFinish لكل استعلام مكتمل. رشّح حسب QueryFinish، الذي يحتوي على المدة النهائية والصفوف والبايتات المقروءة وذروة استخدام الذاكرة:
  5. لكل إصدار من الاستعلام، استخدم المدة الوسيطة لعمليات التشغيل المقاسة. سجّل read_rows وread_bytes وذروة استخدام الذاكرة من عملية التشغيل الأقرب إلى هذا الوسيط، حتى تظل القياسات مرتبطة بعملية تشغيل فعلية.
بالنسبة إلى الاستعلامات الموزعة، لا تمثل memory_usage في سجل QueryFinish الخاص بالاستعلام البادئ ذروة على مستوى المجموعة. استخدم initial_query_id لفحص سجلات QueryFinish الفرعية على العقد المشاركة.
استخدم جدولًا مثل التالي لتنظيم القياسات التمثيلية. راجع system.query_log لمزيد من المعلومات عن حقوله وإعداداته.

نفِّذ استعلامات أبسط تدريجيًا

لتوضيح المقارنات الثلاث، يستخدم المثال عبء العمل المجمّع حسب نطاق زمني. يمكنك تطبيق هذه الطريقة على استعلام آخر من دون اتباع المثال خطوةً بخطوة. إذا لم يتضمن الاستعلام GROUP BY، فتجاوز التشغيل B كما هو موضح أدناه.
1

التشغيل A: قياس الاستعلام الأصلي

نفِّذ الاستعلام كاملًا من دون تغيير عوامل التصفية أو التجميع أو التعبيرات التجميعية أو الفرز أو المخرجات. يحدد ذلك مدة خط الأساس، وعدد الصفوف والبايتات المقروءة، وذروة استخدام الذاكرة.يجمع هذا الاستعلام الرحلات حسب نوع الدفع ويحسب عدة قيم تجميعية:
سجّل قياسات الاستعلام باعتبارها التشغيل A.
2

التشغيل B: الاحتفاظ بالتجميع مع count

احتفظ بعبارات FROM وJOIN وPREWHERE وWHERE ومفاتيح التجميع في الاستعلام. استبدل تعبيراته التجميعية بـ count مجمّع. أزل المعالجة التي تلي التجميع، بما في ذلك الفرز الأصلي وتعبيرات المخرجات.
لا يزال التشغيل B يفحص البيانات ويصفيها، وينفذ أي عمليات ربط، ويكوّن المجموعات. قارن مدته بالتشغيل A لتقدير إسهام التعبيرات التجميعية الأصلية والمعالجة التي تلي التجميع. وقارن أيضًا read_bytes، لأن إزالة التعبيرات التجميعية قد تلغي الحاجة إلى قراءة بعض الأعمدة.إذا لم يتضمن الاستعلام الأصلي GROUP BY، فلا توجد مرحلة تجميع لعزلها. تجاوز التشغيل B وقارن الاستعلام الأصلي مباشرةً بالتشغيل C.
3

التشغيل C: إزالة التجميع

أزل GROUP BY وأرجع قيمة count واحدة. أبقِ عبارات FROM وJOIN وPREWHERE وWHERE من دون تغيير كي تكون المعالجة المتبقية قابلة للمقارنة.
يوفر التشغيل C خط أساس للعمليات التي تحتفظ بها خطة تنفيذه، وليس قياسًا معزولًا للفحص أو التصفية. قارنه بالتشغيل B لتقدير إسهام التجميع. وقارن أيضًا read_bytes، لأن إزالة مفتاح التجميع قد تقلل عدد الأعمدة المقروءة. توضح قيمة count المُعادة عدد الصفوف التي تصل إلى التجميع بعد عوامل التصفية وعمليات الربط المحتفَظ بها.قبل تفسير نتائج التشغيل C، تأكد من أن خطة تنفيذه تقرأ مصدر البيانات المقصود وتطبق عوامل التصفية المحتفَظ بها. قد يغيّر إسقاط أو count يعتمد على البيانات الوصفية طبيعة العمل المنفذ. للحصول على خط أساس قائم على الفحص، عطّل التحسين الظاهر في الخطة في عمليات التشغيل الثلاثة جميعها: استخدم optimize_use_implicit_projections = 0 لإسقاط ضمني، أو optimize_use_projections = 0 لإسقاط صريح، أو optimize_trivial_count_query = 0 لـ count غير مقيّد يُستخرج من البيانات الوصفية للجدول.إذا ظل التشغيل C بطيئًا، فتحقق من العمليات التي يحتفظ بها، بدءًا بالفحص والتصفية. استخدم سجلات الاستعلامات وEXPLAIN للتحقق من عنق الزجاجة المشتبه به قبل تغيير الاستعلام.

تفسير الفروقات

قارن مددًا ممثّلة من عمليات تشغيل متكررة بدلًا من طرح توقيتين منفردين. تشير الفروقات الكبيرة والمتسقة إلى مواضع التحقيق التالية:

قارن الصفوف المقروءة بنتيجة count

قارن قيمة read_rows للتشغيل C بالقيمة التي تُرجعها count. على سبيل المثال، إذا كانت read_rows تساوي 100 مليون وأرجعت count مليونًا واحدًا، فهذا يعني أن ClickHouse فحص نحو 100 صف مصدر لكل صف تم عده. يشير ذلك إلى أن عامل التصفية استبعد معظم الصفوف المقروءة من الجدول، لكنه لا يوضح السبب. هذه النسبة مخصصة لعمليات الفحص البسيطة لجدول واحد. أما في الاستعلامات التي تتضمن مصادر بيانات متعددة أو إسقاطات، ففسّر read_rows باستخدام خطة التنفيذ بدلًا من ذلك. في ClickHouse 25.9 والإصدارات الأحدث، عطّل ذاكرة التخزين المؤقت لشرط الاستعلام والتطبيق الديناميكي لفهارس تخطي البيانات قبل فحص استخدام الفهارس:
ثم استخدم EXPLAIN indexes = 1 لمعرفة الفهارس التي استخدمها ClickHouse، وعدد الأجزاء والحبيبات التي استبعدها كل فهرس. إذا اختار ClickHouse حبيبات أكثر من المتوقع، فتحقق مما إذا كانت عوامل التصفية تتوافق مع مفتاح ترتيب الجدول، وما إذا كان استبعاد الأقسام أو فهرس تخطي البيانات قد يستبعد مزيدًا من الحبيبات. إذا لم تتضمن الخطة قسم Indexes، فهذا يعني أن EXPLAIN لم يُظهر استبعاد الفهارس لهذا الاستعلام. أما الاستعلام التحليلي الذي يفحص الجدول بأكمله، فمن المتوقع أن يقرأ معظم بيانات الجدول.

تحقّق من عنق الزجاجة المُشتبه به

بعد أن تشير المقارنة إلى وجود عنق زجاجة محتمل، تحقّق منه قبل تغيير المخطط أو الاستعلام. استخدم الأدلة المناسبة لمصدر زمن الاستجابة المُشتبه به:
  • إذا كان عنق الزجاجة في الفحص أو التصفية، فاستخدم EXPLAIN indexes = 1 مع الإعدادات الموضحة أعلاه لمعرفة الفهارس التي يستخدمها ClickHouse، وعدد الأجزاء والحبيبات التي يستبعدها كل فهرس. تحقّق مما إذا كانت الخطة تستخدم إسقاطًا ضمنيًا بدلًا من الفحص المتوقع.
  • إذا كان عنق الزجاجة في التجميع حسب المجموعات أو التجميع، فافحص أحداث ملف تعريف الاستعلام ذات الصلة وذروة استخدام الذاكرة.
  • إذا ظل التشغيل C بطيئًا ويحتوي على عمليات ربط، فقارنه باستعلام تشخيصي يزيل عملية ربط واحدة في كل مرة. يشير الانخفاض الكبير في المدة إلى أن عملية الربط المُزالة تسهم بقدر كبير من العمل. ولأن إزالة عملية ربط تغيّر معنى الاستعلام، فاستخدم هذه المقارنة لعزل التوقيت فقط، وفسّر التغييرات في عدد الصفوف بشكل منفصل.
  • إذا كان عنق الزجاجة في عملية أخرى يحتفظ بها التشغيل C، فافحص خطة التنفيذ وأحداث ملف تعريف الاستعلام ذات الصلة.
راجع دليل تشخيص الاستعلامات البطيئة للاطلاع على تفاصيل معلومات الفهرس التي يعرضها EXPLAIN. طبّق تغييرًا مستهدفًا واحدًا، ثم كرر عمليات التشغيل A وB وC في الظروف نفسها. تأكّد من أن التغيير قلّل العمل المستهدف ولم ينقل عنق الزجاجة إلى موضع آخر.

الخطوات التالية

تابع إلى أساليب التحسين لمطابقة عنق الزجاجة المُحتمل مع تغيير مستهدف واحد أو أكثر.
آخر تعديل في ٢٨ أغسطس ٢٠٢٦