2011-07-06 61 views
19

我是R用戶,我經常發現我需要編寫需要對大數據集進行子集的函數(數以百萬計的行)。當我將這些功能用於大量觀察時,如果我不小心如何實現它,它可能會非常耗時。子集的最快方式 - data.table與MySQL

爲此,我有時使用data.table包,這比使用數據框的子集提供了更快的速度。最近,我開始嘗試使用像RMySQL這樣的包,將一些表推送到mysql,並使用該包運行SQL查詢並返回結果。

我發現混合性能改進。對於較小的數據集(百萬),似乎將數據加載到data.table並設置正確的按鍵可以加快子集化。對於較大的數據集(10到100萬),似乎向mysql發送查詢的速度會更快。

想知道是否有人瞭解哪種技術應該更快地返回簡單的子集或聚合查詢,以及這是否取決於數據的大小?我明白在data.table中設置鍵有點類似於創建索引,但除此之外,我沒有更多的直覺。

+0

我知道其他一些人在這裏有更多的經驗,所以我會讓他們用實際答案來闡述它,但我懷疑你會想看看'sqldf'包,它完全符合你的描述,只有它在內存中創建表(我認爲),所以查詢可能運行得更快。 – joran

+0

謝謝,喬蘭!我很想在大型表格中理解這一點。這都是猜測,但我得到的建議是,速度問題可能是由於內存管理/限制造成的。畢竟,在使用數據時。表,不是那些在內存中的表? – exl

+0

事實上,對於大內存將成爲問題的數據,但我相信sqldf也可以使用磁盤數據庫。再一次,我沒有用太多,我提到它是因爲它的一個完整的軟件包圍繞着將數據推送到數據庫,執行sql然後將其返回給R的概念構建。 – joran

回答

25

如果數據適合RAM,data.table會更快。如果你提供了一個例子,它可能會很快變得很明顯,你很糟糕地使用data.table。你是否閱讀過data.table wiki上的「不該做什麼」?

SQL有一個下限,因爲它是一個行存儲。如果數據適合內存(而64位是相當多的),那麼data.table更快,不僅因爲它在RAM中,而且因爲內存中的列是連續的(最小化從RAM到L2的頁面操作的頁面提取)。正確使用data.table,它應該比SQL的下限更快。這在FAQ 3.1中有解釋。如果你在data.table中看到的速度較慢,那麼你錯誤地使用data.table(或者有一個我們需要修復的性能錯誤)的機會非常高。因此,請在閱讀data.table wiki後發佈一些測試。

+1

Doyle - Nice!我也現在正在自己前往維基。我一直都明白Db對於大多數查詢來說速度更快,但現在我可以查看原因以及這些界限是什麼。有時候需要一個正確的方向。 。 。謝謝! – XIVSolutions

2

我不是R用戶,但我對數據庫有一點了解。我相信,MySQL(或任何其他聲譽良好的RDBMS)實際上將會更快地執行子集操作(通常像一個數量級),除非在子集化過程中涉及任何額外的計算。

我懷疑你在小數據集上的性能滯後與連接和數據初始推送到MySQL的開銷有關。連接開銷和數據傳輸時間可能會增加MySQL的操作成本。

但是,對於大於某個最小值的數據集,似乎可以通過數據庫的絕對速度來補償此成本。

我的理解是,SQL可以實現大部分的提取和排序操作,比代碼中的迭代操作快得多。但是必須考慮連接的成本和(在這種情況下)通過網絡線路傳輸數據的初始成本。

我很想聽聽其他人有什麼要說的。 。 。

+0

感謝帖子!只是一個澄清 - 我不會每次迭代都將數據集推送到MySQL;相反,我只是在運行該功能之前做了一次。所以我只需要將R從R推出到MySQL就可以實現迭代,這是一個查詢的子集或值。 – exl

+0

嗯。我仍然對「小」和「大」數據集之間性能統計變化背後的原因感興趣。可能仍然與連接開銷有關,即使沒有推送? (例如連接開銷佔總執行時間的百分比) – XIVSolutions