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
ذات حمولات مختلفة.