Optimization 向R中的数据库发送巨大向量

Optimization 向R中的数据库发送巨大向量,optimization,r,Optimization,R,下午好 在计算了一个相当大的向量(比2^20个元素短一点)之后,我必须将结果存储在数据库中 使用以下简单代码执行脚本大约需要4小时: #Do the processing myVector<-processData(myData) #Sends every thing to the database lapply(myVector,sendToDB) 这就是我的想法 更新 我目前正在尝试加载数据填充命令 我仍然不知道为什么要花这么长时间才能第一次实现lappy的内部功能 解决方案 加载数

下午好

在计算了一个相当大的向量(比2^20个元素短一点)之后,我必须将结果存储在数据库中

使用以下简单代码执行脚本大约需要4小时:

#Do the processing
myVector<-processData(myData)
#Sends every thing to the database
lapply(myVector,sendToDB)
这就是我的想法

更新

我目前正在尝试
加载数据填充
命令

我仍然不知道为什么要花这么长时间才能第一次实现
lappy
的内部功能

解决方案

加载数据填充
确实要快得多。使用
write
逐行写入文件是可以承受的,而
write.table
则更快


对于
lappy
我所经历的开销来自于我在
POSIXct
对象上循环的事实。使用
seq(以及.with=myVector)
然后处理循环中的数据要快得多。

将其写入某个文件并调用LOAD data infle怎么样?这至少应该给出一个基准。顺便问一下:你使用什么样的数据库管理系统

可以使用sqlSave代替sendToDB函数。在内部,它使用一个准备好的insert语句,这应该比单个insert更快


但是,在使用MS SQL的windows平台上,我使用一个单独的函数,该函数首先将数据帧写入csv文件,然后调用bcp批量加载程序。在我的例子中,这比sqlSave快得多。

相对而言,sendToDB()函数的开销很大。该函数必须协商ODBC连接,发送一行数据,然后关闭列表中每个项目的连接。如果您使用的是rodbc,那么使用sqlSave()将整个数据帧复制为表会更有效。根据我的经验,我发现一些数据库(例如SQL Server)在潜在网络上使用sqlSave()时仍然非常慢。在这些情况下,我从R导出到CSV,并使用批量加载程序将文件加载到DB中。我设置了一个外部脚本,通过调用system()来运行批量加载程序。这样,加载在R之外进行,但我的R脚本正在运行该节目

我们可能需要一些详细信息-sendToDB函数中有哪些内容?另外,长度为65k的向量不是特别大,如果函数是快速的,则应该是几乎即时的。在我的系统上,时间(lappy(1:2^16,length))需要0.44s。你是对的,我更正了向量大小,它是650k而不是65k。无论如何,我也不确定这是否是问题所在。函数sendToDB基本上编写SQL查询并将其发送到数据库。我会在问题中加一个skelleton,R对循环不好,这个lappy在C中可以很好地工作,但是在R中你必须做得不同,我不知道“加载数据填充”,这意味着我首先必须将数据写入文件中,所以我只是稍微移动一下这个问题。我使用一个关系数据库,但实际上这个表没有关系,所以它是一个平面数据库加载数据填充只发出一个查询,而不是每行一个查询。因此,如果使用phpmyadmin之类的工具进行DBadministration,您可能会得到更快的结果,并且不会超时。在使用MySQL或PostgreSQL的情况下,有一些很好的包,比如RMySQL和RPostgreSQL。还有一个甲骨文软件包。我已经测试了这两个SQL包,对此我很满意。话虽如此,我真的很想知道你为什么会有问题,因为我已经用这些工具处理了几gb的数据。我将尝试加载数据填充,它看起来非常有效。我猜单次查询效率不够。是的,事实上,我的函数是在
lappy
调用中动态定义的,通道在
lappy
之前打开,之后关闭。但是,既然我使用的是MySQL,那么我就来看看sqlSave。顺便问一下,即使我没有,连接池是否会大大减少悬垂?使用
sqlSave
需要将数据传输到
data.frame
中。我的数据集目前存储在XTS中。当我尝试
testI时,我对XTS对象没有太多经验,所以在这方面我帮不了什么忙。也许还有一个问题?我可能遗漏了一些明显的东西,但是连接池是从哪里来的呢?
sendToDB<-function(id,data) {
  channel<-odbcChannel(...)
  query<-paste("INSERT INTO history VALUE(",id,",\"",data,"\")",sep="")
  sqlQuery(channel,query)
  odbcClose(channel)
}