Skip to main content
إذا تم تحديد SELECT DISTINCT، فلن تبقى في نتيجة الاستعلام إلا الصفوف المميزة. وبذلك، لن يبقى من بين جميع مجموعات الصفوف المتطابقة تمامًا في النتيجة سوى صف واحد فقط. يمكنك تحديد قائمة الأعمدة التي يجب أن تكون قيمها مميزة: SELECT DISTINCT ON (column1, column2,...). وإذا لم يتم تحديد الأعمدة، فستُؤخذ جميعها في الاعتبار. لننظر إلى الجدول:
استخدام DISTINCT من دون تحديد أعمدة:
استخدام DISTINCT مع أعمدة محددة:

DISTINCT و ORDER BY

يدعم ClickHouse استخدام العبارتين DISTINCT و ORDER BY على أعمدة مختلفة ضمن استعلام واحد. وتُنفَّذ العبارة DISTINCT قبل العبارة ORDER BY. انظر إلى الجدول التالي:
اختيار البيانات:
اختيار البيانات باستخدام اتجاه فرز مختلف:
تم اقتطاع الصف 2, 4 قبل الفرز. ضع هذه الخصوصية التنفيذية في الحسبان عند برمجة الاستعلامات.

معالجة NULL

تعمل DISTINCT مع NULL كما لو أن NULL قيمة محددة، وكأن NULL==NULL. وبعبارة أخرى، لا تظهر في نتائج DISTINCT التركيبات المختلفة التي تتضمن NULL إلا مرة واحدة فقط. وهذا يختلف عن طريقة التعامل مع NULL في معظم السياقات الأخرى.

بدائل

يمكن الحصول على النتيجة نفسها بتطبيق GROUP BY على نفس مجموعة القيم المحددة في عبارة SELECT، من دون استخدام أي دوال تجميع. لكن توجد بعض الفروق مقارنةً بنهج GROUP BY:
  • يمكن تطبيق DISTINCT مع GROUP BY في الوقت نفسه.
  • قبل بدء التنفيذ الخارجي، يمكن للاستعلام من دون ORDER BY أن يتوقف فور قراءته عددًا كافيًا من الصفوف المختلفة لتلبية LIMIT.
  • قبل بدء التنفيذ الخارجي وعند حذف ORDER BY، يمكن أيضًا لنطاق LIMIT ... AFTER ... UNTIL من دون ALL أن يوقف الاستعلام بمجرد انتهاء النطاق.
  • تُخرَج كتل البيانات أثناء معالجتها إلى أن يبدأ التنفيذ الخارجي.

DISTINCT في الذاكرة الخارجية

يمكن لـ DISTINCT كتابة بيانات مؤقتة على القرص لمعالجة مجموعات من القيم المميزة التي يتعذّر الاحتفاظ بها في الذاكرة لكبر حجمها. ويتطلب ذلك عمليات إدخال/إخراج إضافية على القرص، وقد يبطئ الاستعلامات. ويتحكم إعدادان في وقت بدء الكتابة على القرص:
  • max_bytes_before_external_distinct يحدد عتبة بالبايت من إجمالي ذاكرة الاستعلام. وقيمته الافتراضية 0 (معطّل).
  • max_bytes_ratio_before_external_distinct يحدد نسبة من الذاكرة المتاحة ضمن حدود الخادم أو المستخدم، تُقاس عند بدء التنفيذ. وقيمته الافتراضية 0.5، ولا يكون له أي تأثير إذا لم ينطبق أي من الحدّين.
وعند انطباق العتبتين معًا، تُستخدم الأصغر. اضبط كلا الإعدادين على 0 لتعطيل الكتابة على القرص. ولا يؤثر max_memory_usage في النسبة. ولتهيئة الكتابة على القرص نسبةً إلى حد ذاكرة الاستعلام، اضبط عتبة مطلقة أقل من ذلك الحد. على سبيل المثال، يستخدم هذا الاستعلام عتبة كتابة على القرص مقدارها 16 ميبي بايت مع حد ذاكرة استعلام يبلغ 256 ميبي بايت:
لا تضع هذه العتبات حدًا أقصى لاستهلاك الذاكرة. اترك مساحة لبقية عمليات معالجة الاستعلام وللكتابة إلى القرص نفسها. كما قد تبدأ الكتابة إلى القرص في وقت أبكر عند وجود ضغط على الذاكرة. يمكن إرجاع الصفوف قبل بدء الكتابة إلى القرص، وإذا تحقق شرط LIMIT في هذه المرحلة فقد ينتهي الاستعلام مبكرًا. وبمجرد بدء الكتابة إلى القرص، يجب قراءة بقية المدخلات قبل التمكّن من إرجاع النتائج المتبقية. وإذا تضمّن الاستعلام ORDER BY، فسترد تلك النتائج بالترتيب المطلوب. عندما يستخدم DISTINCT مدخلات مرتّبة وفق بادئة من مفاتيحه، فإنه لا يكتب إلى القرص. ومع ذلك، قد تستهلك مجموعة كبيرة من الصفوف التي تشترك في البادئة نفسها قدرًا كبيرًا من الذاكرة. وكما هو الحال مع optimize_distinct_in_order، قد تؤدي الكتابة إلى القرص إلى إزالة تكرار القيم ذات الفاصلة العائمة التي تختلف تمثيلاتها الثنائية لكنها متساوية عند المقارنة، بما في ذلك 0.0 و-0.0، أو قيم NaN ذات حمولات مختلفة.
آخر تعديل في ٢٦ سبتمبر ٢٠٢٦