فهم أداء الاستعلامات
اعتبارات عامة
- تحليل الاستعلام وفهمه
- تحسين الاستعلام
- تنفيذ خط الاستعلام
- المعالجة النهائية
مجموعة البيانات
حدِّد الاستعلامات البطيئة
سجلات الاستعلامات
system.query_log.
لكل استعلام مُنفَّذ، يسجّل ClickHouse إحصاءات مثل وقت تنفيذ الاستعلام، وعدد الصفوف المقروءة، واستخدام الموارد مثل CPU، واستخدام الذاكرة، وعدد مرات الوصول إلى ذاكرة التخزين المؤقت لنظام الملفات.
لذلك، يُعَدّ سجل الاستعلام نقطة انطلاق جيدة عند التحقيق في الاستعلامات البطيئة. ويمكنك بسهولة رصد الاستعلامات التي تستغرق وقتًا طويلًا في التنفيذ وعرض معلومات استخدام الموارد لكل منها.
لنحدّد أطول خمسة استعلامات تشغيلًا في مجموعة بيانات سيارات الأجرة في NYC.
query_duration_ms إلى المدة التي استغرقها تنفيذ ذلك الاستعلام المحدد. وبالنظر إلى النتائج في سجلات الاستعلامات، يمكننا أن نرى أن الاستعلام الأول يستغرق 2967ms للتنفيذ، وهو ما يمكن تحسينه.
قد ترغب أيضًا في معرفة الاستعلامات التي تُحمّل النظام أكثر من غيرها، وذلك من خلال فحص الاستعلام الذي يستهلك أكبر قدر من الذاكرة أو CPU.
enable_filesystem_cache على 0 لتحسين إمكانية تكرار النتائج.
لنفهم بصورة أوضح قليلًا ما الذي تحققه هذه الاستعلامات.
- يحسب الاستعلام 1 توزيع المسافات للرحلات التي يزيد متوسط سرعتها على 30 ميلًا في الساعة.
- يعثر الاستعلام 2 على عدد الرحلات ومتوسط تكلفتها أسبوعيًا.
- يحسب الاستعلام 3 متوسط مدة كل رحلة في مجموعة البيانات.
جملة Explain
nyc_taxi.trips_small_inferred، ثم يُطبَّق شرط WHERE لتصفية الصفوف استناداً إلى القيم المحسوبة. بعد ذلك، تُهيَّأ البيانات المصفَّاة للتجميع وتُحسَب الكوانتيلات. وأخيراً، تُرتَّب النتائج وتُعرَض.
يمكننا هنا ملاحظة أنه لم يُستخدم أي مفتاح أساسي، وهذا أمر متوقع إذ لم نُعرِّف أيًّا منها عند إنشاء الجدول. ونتيجةً لذلك، يُجري ClickHouse فحصًا كاملًا للجدول لتنفيذ الاستعلام.
شرح خط المعالجة
يعرض EXPLAIN Pipeline استراتيجية التنفيذ الفعلية للاستعلام، ومن خلاله يمكنك معرفة كيف نفّذ ClickHouse فعليًا خطة الاستعلام العامة التي استعرضناها سابقًا.
المنهجية
user أو tables أو databases من system.query_logs لتضييق نطاق البحث.
بمجرد تحديد الاستعلامات التي تريد تحسينها، يمكنك البدء في العمل عليها. ومن الأخطاء الشائعة التي يرتكبها المطورون في هذه المرحلة تغيير عدة أشياء في الوقت نفسه وإجراء تجارب مخصّصة، ما ينتهي غالبًا إلى نتائج متباينة، والأهم من ذلك، من دون فهم واضح لما جعل الاستعلام أسرع.
يتطلب تحسين الاستعلامات منهجية منظَّمة. لا أتحدث هنا عن قياس أداء متقدم، بل إن وجود عملية بسيطة لفهم كيفية تأثير تغييراتك في أداء الاستعلامات يمكن أن يحقق فائدة كبيرة.
ابدأ بتحديد الاستعلامات البطيئة من سجلات الاستعلامات، ثم افحص التحسينات المحتملة كلًّا على حدة. وعند اختبار الاستعلام، تأكد من تعطيل ذاكرة التخزين المؤقت لنظام الملفات.
يستفيد ClickHouse من التخزين المؤقت لتسريع أداء الاستعلامات في مراحل مختلفة. وهذا جيد لأداء الاستعلامات، لكنه أثناء استكشاف الأخطاء وإصلاحها قد يُخفي اختناقات I/O المحتملة أو مخطط جدول غير مناسب. لهذا السبب، أقترح إيقاف ذاكرة التخزين المؤقت لنظام الملفات أثناء الاختبار. وتأكد من إبقائها مفعّلة في بيئة الإنتاج.بمجرد تحديد التحسينات المحتملة، يُوصى بتنفيذها واحدًا تلو الآخر لتتبّع كيفية تأثيرها في الأداء بشكل أفضل. يوجد أدناه مخطط يصف النهج العام. أخيرًا، انتبه إلى القيم الشاذة؛ فمن الشائع أن يعمل الاستعلام ببطء، إما لأن مستخدمًا نفّذ استعلامًا مكلّفًا مخصّصًا أو لأن النظام كان تحت ضغط لسبب آخر. يمكنك التجميع حسب الحقل normalized_query_hash لتحديد الاستعلامات المكلفة التي تُنفَّذ بانتظام. وغالبًا ما تكون هذه هي الاستعلامات التي ينبغي لك التحقيق فيها.
التحسين الأساسي
Nullable
NULL: mta_tax وpayment_type. ولا ينبغي أن تستخدم بقية الحقول عمودًا من النوع Nullable.
انخفاض التعددية
Strings تحقيق أقصى استفادة من نوع البيانات LowCardinality. وكما هو موضح في الوثائق الخاصة بـ low cardinality، يطبّق ClickHouse ترميز القاموس على أعمدة LowCardinality، مما يعزّز أداء الاستعلامات بشكل ملحوظ.
ومن القواعد العملية البسيطة لتحديد الأعمدة المناسبة لـ LowCardinality أن أي عمود يحتوي على أقل من 10,000 قيمة فريدة يُعد مرشحًا مثاليًا.
يمكنك استخدام استعلام SQL التالي للعثور على الأعمدة ذات العدد المنخفض من القيم الفريدة.
ratecode_id وpickup_location_id وdropoff_location_id وvendor_id، مرشّحةً جيدةً لاستخدام نوع الحقل LowCardinality.
حسّن نوع البيانات
طبّق التحسينات
نلاحظ بعض التحسن في كلٍّ من وقت الاستعلام واستخدام الذاكرة. وبفضل تحسين بنية البيانات، ينخفض الحجم الإجمالي للبيانات التي تمثلها، مما يؤدي إلى تحسين استهلاك الذاكرة وتقليل وقت المعالجة.
لنتحقق من حجم الجداول لمعرفة الفرق.
أهمية المفاتيح الأساسية
الحبيبات في ClickHouse هي أصغر وحدات البيانات التي تُقرأ أثناء تنفيذ الاستعلام. وتحتوي على عدد أقصى ثابت من الصفوف، يحدده index_granularity، وتبلغ قيمته الافتراضية 8192 صفًا. وتُخزَّن الحبيبات بشكل متجاور وتُرتَّب بحسب المفتاح الأساسي.
ويُعد اختيار مجموعة مناسبة من المفاتيح الأساسية أمرًا مهمًا للأداء، بل ومن الشائع أيضًا تخزين البيانات نفسها في جداول مختلفة واستخدام مجموعات مختلفة من المفاتيح الأساسية لتسريع مجموعة معينة من الاستعلامات.
وتتيح لك خيارات أخرى يدعمها ClickHouse، مثل Projection أو العرض المادي، استخدام مجموعة مختلفة من المفاتيح الأساسية للبيانات نفسها. وسيتناول الجزء الثاني من سلسلة المدوّنة هذه ذلك بمزيد من التفصيل.
اختر المفاتيح الأساسية
- استخدم الحقول التي يجري التصفية بناءً عليها في معظم الاستعلامات
- اختر الأعمدة ذات عدد القيم المميزة الأقل أولًا
- ضع في اعتبارك تضمين مكوّن زمني في مفتاحك الأساسي، لأن التصفية حسب الوقت في مجموعة بيانات تحتوي على طابع زمني أمر شائع جدًا.
passenger_count وpickup_datetime وdropoff_datetime.
عدد القيم المميزة للحقل passenger_count صغير (24 قيمة فريدة)، كما يُستخدم في استعلاماتنا البطيئة. ونضيف أيضًا حقول الطابع الزمني (pickup_datetime وdropoff_datetime) لأنها تُستخدم كثيرًا في التصفية.
أنشئ جدولًا جديدًا بهذه المفاتيح الأساسية، ثم أعد إدخال البيانات.
| الاستعلام 1 | |||
|---|---|---|---|
| التشغيل 1 | التشغيل 2 | التشغيل 3 | |
| الزمن المنقضي | 1.699 sec | 1.353 sec | 0.765 sec |
| الصفوف المعالجة | 329.04 مليون | 329.04 مليون | 329.04 مليون |
| ذروة الذاكرة | 440.24 MiB | 337.12 MiB | 444.19 MiB |
| الاستعلام 2 | |||
|---|---|---|---|
| التشغيل 1 | التشغيل 2 | التشغيل 3 | |
| الزمن المنقضي | 1.419 sec | 1.171 sec | 0.248 sec |
| الصفوف المعالجة | 329.04 مليون | 329.04 مليون | 41.46 مليون |
| ذروة الذاكرة | 546.75 MiB | 531.09 MiB | 173.50 MiB |
| الاستعلام 3 | |||
|---|---|---|---|
| التنفيذ 1 | التنفيذ 2 | التنفيذ 3 | |
| الزمن المنقضي | 1.414 sec | 1.188 sec | 0.431 sec |
| الصفوف المُعالجة | 329.04 million | 329.04 million | 276.99 million |
| ذروة الذاكرة | 451.53 MiB | 265.05 MiB | 197.38 MiB |