Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

مفتاح التقسيم مخصص

التقسيم متاح لجداول عائلة MergeTree، بما في ذلك الجداول المكررة والعروض المادية.

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

يُحدَّد القسم في العبارة PARTITION BY expr عند إنشاء جدول. ويمكن أن يكون مفتاح التقسيم أي تعبير مشتق من أعمدة الجدول. على سبيل المثال، لتحديد التقسيم حسب الشهر، استخدم التعبير toYYYYMM(date_column):

CREATE TABLE visits
(
    VisitDate Date,
    Hour UInt8,
    ClientID UUID
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(VisitDate)
ORDER BY Hour;

يمكن أيضًا أن يكون مفتاح التقسيم مجموعة من التعبيرات (على غرار المفتاح الأساسي). على سبيل المثال:

ENGINE = ReplicatedCollapsingMergeTree('/clickhouse/tables/name', 'replica1', Sign)
PARTITION BY (toMonday(StartDate), EventType)
ORDER BY (CounterID, StartDate, intHash32(UserID));

في هذا المثال، نضبط التقسيم بحسب أنواع الأحداث التي وقعت خلال الأسبوع الحالي.

بشكل افتراضي، لا يكون مفتاح التقسيم ذي الفاصلة العائمة مدعومًا. لاستخدامه، فعِّل الإعداد allow_floating_point_partition_key.

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

استخدم جدول system.parts لعرض أجزاء الجدول والأقسام. على سبيل المثال، لنفترض أن لدينا جدول visits مع تقسيم حسب الشهر. لننفّذ استعلام SELECT على جدول system.parts:

SELECT
    partition,
    name,
    active
FROM system.parts
WHERE table = 'visits'
┌─partition─┬─name──────────────┬─active─┐
│ 201901    │ 201901_1_3_1      │      0 │
│ 201901    │ 201901_1_9_2_11   │      1 │
│ 201901    │ 201901_8_8_0      │      0 │
│ 201901    │ 201901_9_9_0      │      0 │
│ 201902    │ 201902_4_6_1_11   │      1 │
│ 201902    │ 201902_10_10_0_11 │      1 │
│ 201902    │ 201902_11_11_0_11 │      1 │
└───────────┴───────────────────┴────────┘

يحتوي العمود partition على أسماء الأقسام. يوجد قسمان في هذا المثال: 201901 و201902. يمكنك استخدام قيمة هذا العمود لتحديد اسم القسم في استعلامات ALTER … PARTITION.

يحتوي العمود name على أسماء أجزاء بيانات القسم. يمكنك استخدام هذا العمود لتحديد اسم الجزء في استعلام ALTER ATTACH PART.

لنحلّل اسم الجزء: 201901_1_9_2_11:

  • 201901 هو اسم القسم.
  • 1 هو الرقم الأدنى لكتلة البيانات.
  • 9 هو الرقم الأقصى لكتلة البيانات.
  • 2 هو مستوى الجزء (عمق شجرة الدمج التي تكوَّن منها).
  • 11 هو إصدار التعديل (إذا خضع الجزء لتعديل)

يعرض العمود active حالة الجزء. تعني 1 أنه نشط، وتعني 0 أنه غير نشط. وتشمل الأجزاء غير النشطة، على سبيل المثال، الأجزاء الأصلية المتبقية بعد دمجها في جزء أكبر. كما تُصنَّف أجزاء البيانات التالفة أيضًا على أنها غير نشطة.

كما ترى في المثال، توجد عدة أجزاء منفصلة للقسم نفسه (على سبيل المثال، 201901_1_3_1 و201901_1_9_2). وهذا يعني أن هذه الأجزاء لم تُدمج بعد. يدمج ClickHouse أجزاء البيانات المُدرجة دوريًا، عادةً بعد نحو 15 دقيقة من الإدراج. بالإضافة إلى ذلك، يمكنك إجراء دمج غير مجدول باستخدام استعلام OPTIMIZE. مثال:

OPTIMIZE TABLE visits PARTITION 201902;
┌─partition─┬─name─────────────┬─active─┐
│ 201901    │ 201901_1_3_1     │      0 │
│ 201901    │ 201901_1_9_2_11  │      1 │
│ 201901    │ 201901_8_8_0     │      0 │
│ 201901    │ 201901_9_9_0     │      0 │
│ 201902    │ 201902_4_6_1     │      0 │
│ 201902    │ 201902_4_11_2_11 │      1 │
│ 201902    │ 201902_10_10_0   │      0 │
│ 201902    │ 201902_11_11_0   │      0 │
└───────────┴──────────────────┴────────┘

سيتم حذف الأجزاء غير النشطة بعد الدمج بنحو 10 دقائق.

وثمة طريقة أخرى لعرض مجموعة من الأجزاء والأقسام، وهي الانتقال إلى مجلد الجدول: /var/lib/clickhouse/data/<database>/<table>/. على سبيل المثال:

/var/lib/clickhouse/data/default/visits$ ls -l
total 40
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  1 16:48 201901_1_3_1
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 16:17 201901_1_9_2_11
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 15:52 201901_8_8_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 15:52 201901_9_9_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 16:17 201902_10_10_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 16:17 201902_11_11_0
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 16:19 201902_4_11_2_11
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  5 12:09 201902_4_6_1
drwxr-xr-x 2 clickhouse clickhouse 4096 Feb  1 16:48 detached

المجلدات '201901_1_1_0' و'201901_1_7_1' وما إلى ذلك هي أدلة الأجزاء. ينتمي كل جزء إلى قسم مقابلة، ولا يحتوي إلا على بيانات شهر معيّن (يستخدم الجدول في هذا المثال التقسيم حسب الشهر).

يحتوي دليل detached على الأجزاء التي فُصلت عن الجدول باستخدام استعلام DETACH. كما تُنقل الأجزاء التالفة إلى هذا الدليل بدلًا من حذفها. لا يستخدم الخادوم الأجزاء الموجودة في دليل detached. يمكنك إضافة البيانات في هذا الدليل أو حذفها أو تعديلها في أي وقت، لكن الخادوم لن يعلم بذلك إلى أن تُشغّل استعلام ATTACH.

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

يتيح لك ClickHouse تنفيذ عمليات على الأقسام: حذفها، أو نسخها من جدول إلى آخر، أو إنشاء نسخة احتياطية. راجع قائمة جميع العمليات في قسم التعامل مع الأقسام والأجزاء.

تحسين GROUP BY باستخدام مفتاح التقسيم

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

المثال الشائع هو:

CREATE TABLE session_log
(
    UserID UInt64,
    SessionID UUID
)
ENGINE = MergeTree
PARTITION BY sipHash64(UserID) % 16
ORDER BY tuple();

SELECT
    UserID,
    COUNT()
FROM session_log
GROUP BY UserID;

العوامل الأساسية لتحقيق أداء جيد هي:

  • يجب أن يكون عدد الأقسام المشاركة في الاستعلام كبيرًا بما يكفي (أكثر من max_threads / 2)، وإلا فلن يستفيد الاستعلام من موارد الجهاز على النحو الأمثل
  • يجب ألا تكون الأقسام صغيرة جدًا، حتى لا تتحول المعالجة الدفعية إلى معالجة صفًا تلو الآخر
  • يجب أن تكون الأقسام متقاربة في الحجم، بحيث تنفذ جميع خيوط التنفيذ مقدارًا متقاربًا من العمل

الإعدادات ذات الصلة هي:

  • allow_aggregate_partitions_independently - يتحكم في ما إذا كان استخدام هذا التحسين مُمكّنًا
  • force_aggregate_partitions_independently - يفرض استخدامه عندما يكون قابلًا للتطبيق من حيث صحة النتائج، لكن يتم تعطيله بواسطة المنطق الداخلي الذي يقدّر مدى جدواه
  • max_number_of_partitions_for_independent_aggregation - حد صارم لأقصى عدد من الأقسام يمكن أن يحتويه الجدول
Navigation