الانتقال إلى المحتوى الرئيسي
يتيح الإعداد الجديد allow_asynchronous_read_from_io_pool_for_merge_tree أن يكون عدد خيوط القراءة (streams) أكبر من عدد الخيوط في بقية مسار تنفيذ الاستعلام. عادةً ما يتحكم الإعداد max_threads في عدد خيوط القراءة المتوازية وخيوط معالجة الاستعلام المتوازية: تُقرأ البيانات ‘بالترتيب’، عمودًا تلو الآخر، من القرص.

قراءة البيانات غير المتزامنة

يتيح الإعداد الجديد allow_asynchronous_read_from_io_pool_for_merge_tree أن يكون عدد خيوط القراءة (streams) أكبر من عدد الخيوط في بقية مسار تنفيذ الاستعلام، وذلك لتسريع الاستعلامات الباردة على خدمات ClickHouse Cloud ذات موارد CPU المحدودة، ولتحسين أداء الاستعلامات المقيّدة بعمليات الإدخال/الإخراج. عند تفعيل هذا الإعداد، يتحكم الإعداد max_streams_for_merge_tree_reading في عدد خيوط القراءة: تُقرأ البيانات بشكل غير متزامن وبالتوازي من أعمدة مختلفة. لاحظ أنه يوجد أيضًا الإعداد max_streams_to_max_threads_ratio لتهيئة النسبة بين عدد خيوط القراءة (streams) وعدد الخيوط في بقية مسار تنفيذ الاستعلام. ومع ذلك، في اختبارات الأداء، لم يكن تأثيره كبيرًا بقدر الإعداد max_streams_for_merge_tree_reading

ماذا عن optimize_read_in_order؟

باستخدام تحسين optimize_read_in_order، يمكن لـ ClickHouse تجنّب إعادة فرز البيانات في الذاكرة إذا كان ترتيب الفرز في الاستعلامات يعكس الترتيب الفعلي للبيانات على القرص، لكن ذلك يتطلب قراءة البيانات بالترتيب (على عكس القراءة غير المتزامنة):

تتقدّم optimize_read_in_order على القراءة غير المتزامنة

عندما يكتشف ClickHouse أنه يمكن تطبيق تحسين optimize_read_in_order، يتم تجاهل / تعطيل الإعداد allow_asynchronous_read_from_io_pool_for_merge_tree.

مثال يوضّح كل ما سبق

SELECT getSetting('max_threads');

┌─getSetting('max_threads')─┐
│                        10 │
└───────────────────────────┘
  • تحقّق من خط تنفيذ الاستعلام باستخدام العدد الافتراضي من خيوط التنفيذ لكلٍّ من قراءة البيانات ومعالجتها
EXPLAIN PIPELINE
SELECT *
FROM uk_price_paid;

┌─explain──────────────────────┐
│ (Expression)                 │
│ ExpressionTransform × 10     │
│   (ReadFromMergeTree)        │
│   MergeTreeThread × 10 0 → 1 │
└──────────────────────────────┘
  • تحقّق من مسار الاستعلام باستخدام 60 خيط قراءة غير متزامن، وبالعدد الافتراضي من خيوط التنفيذ لبقية مسار تنفيذ الاستعلام
EXPLAIN PIPELINE
SELECT *
FROM uk_price_paid
SETTINGS
    allow_asynchronous_read_from_io_pool_for_merge_tree = 1,
    max_streams_for_merge_tree_reading = 60;

┌─explain────────────────────────┐
│ (Expression)                   │
│ ExpressionTransform × 10       │
│   (ReadFromMergeTree)          │
│   Resize 60 → 10               │
│     MergeTreeThread × 60 0 → 1 │
└────────────────────────────────┘
  • تحقّق من مسار تنفيذ الاستعلام باستخدام 20 مؤشر ترابط لقراءة البيانات ومعالجتها
EXPLAIN PIPELINE
SELECT *
FROM uk_price_paid
SETTINGS
    max_threads = 20;

┌─explain──────────────────────┐
│ (Expression)                 │
│ ExpressionTransform × 20     │
│   (ReadFromMergeTree)        │
│   MergeTreeThread × 20 0 → 1 │
└──────────────────────────────┘
  • تحقّق من مسار الاستعلام باستخدام 60 مؤشر ترابط للقراءة غير المتزامنة و20 مؤشر ترابط لباقي مسار تنفيذ الاستعلام
EXPLAIN PIPELINE
SELECT *
FROM uk_price_paid
SETTINGS
    max_threads = 20,
    allow_asynchronous_read_from_io_pool_for_merge_tree = 1,
    max_streams_for_merge_tree_reading = 60;

┌─explain────────────────────────┐
│ (Expression)                   │
│ ExpressionTransform × 20       │
│   (ReadFromMergeTree)          │
│   Resize 60 → 20               │
│     MergeTreeThread × 60 0 → 1 │
└────────────────────────────────┘
  • تحقّق من مسار الاستعلام مع 60 خيط قراءة غير متزامن و20 خيطًا لبقية مسار تنفيذ الاستعلام عندما يمكن تطبيق تحسين optimize_read_in_order
EXPLAIN PIPELINE
SELECT *
FROM uk_price_paid
ORDER BY postcode1, postcode2
SETTINGS
    max_threads = 20,
    allow_asynchronous_read_from_io_pool_for_merge_tree= 1,
    max_streams_for_merge_tree_reading= 60;

┌─explain───────────────────────────┐
│ (Expression)                      │
│ ExpressionTransform               │
│   (Sorting)                       │
│   MergingSortedTransform 20 → 1   │
│     (Expression)                  │
│     ExpressionTransform × 20      │
│       (ReadFromMergeTree)         │
│       MergeTreeInOrder × 20 0 → 1 │
└───────────────────────────────────┘

-- note that this is equivalent to disabling allow_asynchronous_read_from_io_pool_for_merge_tree

EXPLAIN PIPELINE
SELECT *
FROM uk_price_paid
ORDER BY postcode1, postcode2
SETTINGS
    max_threads = 20,
    allow_asynchronous_read_from_io_pool_for_merge_tree = 0,
    max_streams_for_merge_tree_reading = 0;

┌─explain───────────────────────────┐
│ (Expression)                      │
│ ExpressionTransform               │
│   (Sorting)                       │
│   MergingSortedTransform 20 → 1   │
│     (Expression)                  │
│     ExpressionTransform × 20      │
│       (ReadFromMergeTree)         │
│       MergeTreeInOrder × 20 0 → 1 │
└───────────────────────────────────┘

-- note that you can enforce allow_asynchronous_read_from_io_pool_for_merge_tree by disabling optimize_read_in_order

EXPLAIN PIPELINE
SELECT *
FROM uk_price_paid
ORDER BY
    postcode1 ASC,
    postcode2 ASC
SETTINGS
    max_threads = 20,
    allow_asynchronous_read_from_io_pool_for_merge_tree = 1,
    max_streams_for_merge_tree_reading = 60,
    optimize_read_in_order = 0;

┌─explain──────────────────────────────┐
│ (Expression)                         │
│ ExpressionTransform                  │
│   (Sorting)                          │
│   MergingSortedTransform 20 → 1      │
│     MergeSortingTransform × 20       │
│       (Expression)                   │
│       ExpressionTransform × 20       │
│         (ReadFromMergeTree)          │
│         Resize 60 → 20               │
│           MergeTreeThread × 60 0 → 1 │
└──────────────────────────────────────┘

آخر تعديل في ٢٩ يونيو ٢٠٢٦