2011-07-06 16 views
19

Jestem użytkownikiem R i często stwierdzam, że muszę pisać funkcje, które wymagają podzbioru dużych zestawów danych (10 miliony wierszy). Kiedy stosuję takie funkcje w wielu obserwacjach, może to być bardzo czasochłonne, jeśli nie jestem ostrożny, jak go zaimplementuję.Najszybszy sposób na podzbiór - data.table vs. MySQL

W tym celu korzystałem czasami z pakietu data.table, który zapewnia znacznie większe prędkości niż dzielenie przy użyciu ramek danych. Ostatnio zacząłem eksperymentować z pakietami takimi jak RMySQL, przesyłając kilka tabel do mysql i używając pakietu do uruchamiania kwerend SQL i zwracania wyników.

Znalazłem mieszane ulepszenia wydajności. W przypadku mniejszych zestawów danych (milionów) wydaje się, że ładowanie danych do pliku data.table i ustawianie odpowiednich klawiszy powoduje szybsze tworzenie podzbiorów. W przypadku większych zestawów danych (od 10 do 100 s), wydaje się, że wysyłanie zapytania do mysql porusza się szybciej.

Zastanawiało się, czy ktoś ma wgląd w to, która technika powinna szybciej zwracać proste zapytania podzbioru lub agregacji i czy powinno to zależeć od wielkości danych? Rozumiem, że ustawianie kluczy w data.table jest w pewnym sensie analogiczne do tworzenia indeksu, ale nie mam o wiele więcej intuicji poza tym.

+0

Wiem, że niektórzy inni ludzie mają więcej doświadczenia z tym, więc pozwolę im wyjaśnić na podstawie rzeczywistych odpowiedzi, ale podejrzewam, że będziesz chciał spojrzeć na pakiet 'sqldf', który robi dokładnie to, co ty. opisując, tylko on tworzy tabelę w pamięci (chyba), więc zapytania mogą działać znacznie szybciej. – joran

+0

dzięki, joran! Bardzo chciałbym to zrozumieć w kontekście dużych tabel. To wszystko spekulacje, ale dostałem radę, że problemy z szybkością, które mam, mogą wynikać z zarządzania pamięcią/ograniczeń. Wszakże przy korzystaniu z danych.tabela, czy te tabele też nie są w pamięci? – exl

+0

Rzeczywiście, dla danych, które dużą pamięć będzie problemem, ale wierzę, że sqldf może również używać dyskowych dysków. Ponownie, nie użyłem go zbyt wiele, wspomniałem o tym, ponieważ jest to cały pakiet zbudowany wokół koncepcji przesyłania danych do db, wykonywania sql, a następnie zwracania go do R. – joran

Odpowiedz

25

Jeśli dane mieszczą się w pamięci RAM, data.table jest szybsza. Jeśli podasz przykład, prawdopodobnie szybko stanie się oczywiste, że źle korzystasz z data.table. Czy przeczytałeś "do zrobienia i nie" na data.table wiki?

SQL ma niższą granicę, ponieważ jest magazynem wierszy. Jeśli dane mieszczą się w pamięci RAM (i 64-bitowej jest całkiem sporo), to data.table jest szybsza nie tylko dlatego, że znajduje się w pamięci RAM, ale dlatego, że kolumny sąsiadują z pamięcią (minimalizując pobieranie stron z pamięci RAM do L2 w przypadku operacji na kolumnach). Poprawnie używaj opcji data.table i powinna być szybsza niż dolna granica SQL. Zostało to wyjaśnione w FAQ 3.1. Jeśli widzisz wolniej z data.table, szanse są bardzo wysokie, że używasz nieprawidłowego pliku data.table (lub istnieje błąd wydajności, który musimy naprawić). Opublikuj więc niektóre testy, po przeczytaniu wiki data.table.

+1

Doyle - Nice! Ja też teraz idę do wiki. Zawsze rozumiałem, że Db jest szybsze w przypadku większości zapytań, ale teraz mogę sprawdzić, dlaczego i jakie są granice. Czasami potrzebny jest punkt we właściwym kierunku. . . Dzięki! – XIVSolutions

2

Nie jestem użytkownikiem R, ale wiem trochę o bazach danych. Sądzę, że MySQL (lub jakikolwiek inny renomowany RDBMS) faktycznie wykona twoje operacje podzestawu szybciej (przez, na przykład, rząd wielkości, zwykle) z wyjątkiem dodatkowych obliczeń związanych z procesem podzestawu.

Podejrzewam, że opóźnienie wydajności w małych zestawach danych wiąże się z kosztem połączenia i początkowego przekazywania danych do MySQL. Najprawdopodobniej moment, w którym połączenie i czas przesyłania danych zwiększają koszty twojej operacji, niż MySQL cię oszczędza.

Jednak w przypadku zbiorów danych większych niż określone minimum wydaje się, że koszt ten jest rekompensowany przez samą szybkość bazy danych.

Rozumiem, że SQL może uzyskać większość operacji pobierania i sortowania znacznie szybciej niż operacje iteracyjne w kodzie. Ale trzeba wziąć pod uwagę koszt połączenia i (w tym przypadku) początkowy transfer danych przez sieć.

Będę zainteresowany, aby usłyszeć, co inni mają do powiedzenia. . .

+0

dzięki za post! tylko wyjaśnienie - nie przesyłaj datasetów do MySQL w każdej iteracji; raczej po prostu robię to raz przed uruchomieniem funkcji. Tak więc muszę tylko wypchnąć z R do MySQL, ponieważ iteracja zasięgu jest wartością lub wektorem zapytania do podzbioru. – exl

+0

Hmm. Nadal będę zainteresowany przyczynami zmiany statystyk wydajności między "małymi" i "dużymi" zbiorami danych. Prawdopodobnie nadal związane z połączeniem na górze, nawet bez push? (np. czas na połączenie jako procent całkowitego czasu wykonania) – XIVSolutions

Powiązane problemy