最快的子集生成方法—data.table与MySQL

最快的子集生成方法—data.table与MySQL,mysql,r,rmysql,data.table,Mysql,R,Rmysql,Data.table,我是一个R用户,我经常发现我需要编写需要对大型数据集(10百万行)进行子集设置的函数。当我在大量观察中应用这些函数时,如果我不小心如何实现它,它可能会非常耗时 为此,我有时使用data.table包,这比使用数据帧进行子集设置的速度快得多。最近,我开始试验RMySQL之类的包,将一些表推送到mysql,并使用该包运行sql查询和返回结果 我发现性能的改进有好有坏。对于较小的数据集(数百万),似乎将数据加载到data.table并设置正确的键有助于更快地进行子集设置。对于较大的数据集(10到100

我是一个R用户,我经常发现我需要编写需要对大型数据集(10百万行)进行子集设置的函数。当我在大量观察中应用这些函数时,如果我不小心如何实现它,它可能会非常耗时

为此,我有时使用data.table包,这比使用数据帧进行子集设置的速度快得多。最近,我开始试验RMySQL之类的包,将一些表推送到mysql,并使用该包运行sql查询和返回结果

我发现性能的改进有好有坏。对于较小的数据集(数百万),似乎将数据加载到data.table并设置正确的键有助于更快地进行子集设置。对于较大的数据集(10到100百万),向mysql发送查询的速度似乎更快


我想知道是否有人知道哪种技术应该更快地返回简单的子集或聚合查询,这是否应该取决于数据的大小?我知道在data.table中设置键在某种程度上类似于创建索引,但除此之外,我没有更多的直觉。

我不是R用户,但我对数据库略知一二。我相信MySQL(或任何其他著名的RDBMS)实际上会更快地执行子集操作(通常是一个数量级),除非在子集过程中涉及任何额外的计算

我怀疑您在小数据集上的性能滞后与连接费用和将数据初始推送到MySQL有关。在某种程度上,连接开销和数据传输时间增加的操作成本可能比MySQL节省的成本还要多

然而,对于大于某个最小值的数据集,这一成本似乎可以通过数据库的绝对速度得到补偿

我的理解是,SQL可以比代码中的迭代操作更快地完成大多数抓取和排序操作。但必须考虑连接成本和(在本例中)通过网络线进行的初始数据传输


我很想听听别人怎么说

如果数据适合RAM,data.table会更快。如果您提供一个示例,很快就会发现您使用的data.table很糟糕。你读过报纸上的“做和不做”吗


SQL有一个下限,因为它是行存储。如果数据适合RAM(64位是相当大的一位),那么data.table会更快,不仅因为它在RAM中,而且因为列在内存中是连续的(最小化从RAM到L2的页获取以进行列操作)。正确使用data.table,它应该比SQL的下限快。常见问题解答3.1对此进行了解释。如果您看到data.table的速度变慢,那么您错误地使用data.table的可能性很高(或者存在需要修复的性能缺陷)。因此,请在阅读data.table wiki之后发布一些测试。

谢谢您的帖子!只是澄清一下——我不会每次迭代都将数据集推送到MySQL;相反,我只是在运行函数之前做一次。所以我只需要从R到MySQL,因为reach迭代是一个值或一个向量,用于查询subset on.Hmm。我仍然会对“小”和“大”数据集之间性能统计数据变化背后的原因感兴趣。即使没有推送,也可能与连接开销有关?(例如,连接开销占总执行时间的百分比)我知道这里的其他一些人对此有更多的经验,因此我将让他们用实际的答案对此进行阐述,但我想您可能想看看
sqldf
包,它正是您所描述的,只是它在内存中创建了表(我想)因此,查询可能会运行得更快。谢谢,joran!我渴望在大型表格的背景下理解这一点。这都是猜测,但我得到的建议是,速度问题可能是由于内存管理/限制造成的。毕竟,当使用data.table时,这些表不也在内存中吗?事实上,对于数据来说,大内存将是一个问题,但我相信sqldf也可以使用磁盘数据库。同样,我没有太多地使用它,我提到了它,因为它是一个围绕着将数据推送到数据库、执行sql然后将其返回到R的概念构建的完整包。如果将sqldf与SQLite一起使用,那么
sqldf(“…sql语句…”,dbname=tempfile())
使用磁盘,但没有
dbname=
arg,它使用内存。如果您通过RMySQL将sqldf与MySQL一起使用,那么默认情况下它使用
dbname=“test”
。Doyle-Nice!我现在也要去维基了。我一直都明白,对于大多数查询来说,数据库速度更快,但现在我可以检查一下原因,以及这些界限是什么。有时一个人需要一个指向正确方向的点。谢谢