2014-05-22 11 views
6

Zauważa, że ​​documentation, że LIMIT klauzula . Prowadziłem tabelę SELECT na więcej niż 800,000 rekordach z LIMIT 1, ale zawsze zwracam mi ten sam rekord.Czy klauzula LIMIT w HIVE jest naprawdę losowa?

Używam dystrybucji Shark i zastanawiam się, czy ma to coś wspólnego z tym nieoczekiwanym zachowaniem? Wszelkie przemyślenia będą mile widziane.

Dzięki Visakh

+3

Nie wiem HIVE, więc nie odpowiem. W większości RDBMS losowość zadeklarowana w użyciu LIMIT wynika z faktu, że to, które wiersze otrzymasz, zależy od tego, jak optymalizator zdecyduje się je uzyskać. Innymi słowy, jeśli chcesz mieć określone wiersze, musisz zadeklarować je jawnie (zwykle z ORDER BY). Nie oznacza to, że silnik toczy się za każdym razem, gdy wykonujesz zapytanie, oznacza to tylko, że nie możesz oczekiwać, że wynik będzie zawsze taki sam. – Frazz

+0

W takim przypadku, czy uważasz, że lepiej byłoby utworzyć sekwencję, przypisać do rekordów wyjściowych, a następnie wybrać losowo? Czy zdajesz sobie sprawę z jakiejkolwiek standardowej w branży metody pobierania prawdziwie losowych rekordów z dowolnego RDBMS? – visakh

+1

Wydaje się, że 'HIVE' obsługuje' RAND() '. Tak więc myślę, wykonując 'ORDER BY RAND()', a następnie 'LIMIT 1' działa. – visakh

Odpowiedz

4

Chociaż dokumentacja stwierdza zwraca wiersze losowo, nie jest to faktycznie prawda.

Zwraca "wybrane wiersze losowo", tak jak pojawia się w bazie danych, bez żadnego miejsca/kolejności według zdania. Oznacza to, że nie jest tak naprawdę losowy (lub losowo wybrany), jak można by pomyśleć, tylko, że kolejność, w której wiersze są zwracane, nie może zostać ustalona.

Gdy tylko uderzysz tam o numer order by x DESC limit 5, zwróci on 5 ostatnich wierszy, z których wybierzesz.

dostać wiersze zwrócone w sposób losowy, trzeba by użyć czegoś takiego: order by rand() LIMIT 1

jednak może to mieć wpływ prędkości jeśli indeksy nie są ustawione prawidłowo. Zwykle robię min/max, aby uzyskać identyfikatory na stole, a następnie zrobić losową liczbę między nimi, a następnie wybrać te rekordy (w twoim przypadku byłby to tylko 1 rekord), który wydaje się być szybszy niż wykonanie bazy danych praca, zwłaszcza na dużym zbiorze

+0

Dziękuję ... widziałem to samo [tutaj] (http://mail-archives.apache.org/mod_mbox/hive-user/201208.mbox/%3C899850488-[email protected] b2.c15.bise7.blackberry% 3E) – visakh

+0

Ponieważ jestem na 'Shark', indeksy i tak nie są obsługiwane. A mój stół jest zbuforowany, więc na razie wydajność nie jest problemem ... :-) – visakh

+0

Fajnie. Cieszę się, że mogę pomóc wskazać ci właściwy kierunek :) – user3036342

8

aby być bezpiecznym chcesz użyć

select * from tabela

rozprowadzać przez rand()

sortowania przez rand()

limit 10000;

0

Dokumentacja mogła zostać zaktualizowana, ponieważ to pytanie zostało pierwotnie opublikowane w 2014 r., Ale od grudnia 2017 r. Dokumentacja brzmi teraz: "Poniższe zapytanie zwraca 5 arbitralnych klientów".

W tym przypadku "arbitralny" oznacza, że ​​metoda wyboru nie jest deterministyczna lub może nie być warta udokumentowania. Innymi słowy, nie należy liczyć na to, jako niezawodnej metody uzyskiwania określonego podzbioru rekordów (np. Do pobierania próbek). Powinieneś używać klauzuli Limit bez klauzuli "Zamawiaj", jeśli szukasz możliwości i chcesz jak najszybciej uzyskać mały zestaw wyników (np. Dla celów kontroli jakości). W przeciwnym razie użyj jednego z następujących porządków: Sortuj według, Klastra według lub Rozłóż według/Sortuj według.

Powiązane problemy