select count(distinct user)
from some_table;
To zapytanie wykonuje liczenie po stronie mapy. Każdy element odwzorowujący emituje jedną wartość, liczbę. Następnie wszystkie wartości muszą zostać zsumowane, aby uzyskać całkowitą liczbę, a to jest zadaniem pojedynczego reduktora.
select count(*) from
(select user
from some_table
group by user) q;
To zapytanie składa się z dwóch etapów. Na etapie 1 GROUP BY agreguje użytkowników po stronie mapy i emituje jedną wartość dla każdego użytkownika. Dane wyjściowe muszą być następnie agregowane po stronie zmniejszonej, , ale można użyć wielu reduktorów. Na etapie 2 wykonano COUNT
, po stronie mapy, a następnie końcowy wynik jest agregowany za pomocą jednego pojedynczego reduktora.
Więc jeśli masz bardzo dużą liczbę podziałów po stronie mapy, to pierwsze zapytanie będzie musiało zsumować bardzo dużą liczbę wyników jednej wartości. Druga kwerenda może korzystać z wielu reduktorów po stronie redukcji etapu 1, a następnie na etapie 2 będzie mieć mniejsze zadanie dla samotnego reduktora na końcu.
Zwykle nie jest to optymalizacja. Trzeba by mieć znaczną liczbę podziałów map dla reduktora kwerendy 1, aby stać się problemem. Druga kwerenda ma dwa etapy i to samo będzie wolniejsze niż zapytanie 1 (etap 2 nie może się rozpocząć, dopóki etap 1 nie zostanie całkowicie zakończony). Tak więc, podczas gdy rozumiem, że otrzymałem jakąś radę, byłbym sceptyczny, gdyby nie dokonano właściwego pomiaru i wykazałbym poprawę.
Nie rozumiem twojego pytania. Pytasz, dlaczego wersja "group by'" jest szybsza? Jeśli tak, to dlaczego uważasz, że jest to szybsze? Czytałeś to gdzieś lub widziałeś, że zachowuje się w ten sposób? –
po prostu użyj EXPLAIN – Bohdan