6

我对远处的行业实力数据库进行了许多 SQL 查询,但接收结果需要很长时间。当我的带有 R 的计算机几乎靠近数据库时,它的速度要快得多,这让我相信这是我的计算机和数据库之间的延迟是瓶颈,并且运行并行查询可能会加快速度。我们在不同的大陆。

这是一个不并行的工作版本:

doQueries <- function(filenameX, inp1, inp2) {
  print(paste("Starting:", inp1, inp2, ",saving to", filenameX, sep=" "))
  # Here should the query be (using RODBC)
  # save(queryresults, file="filenameX")
}

input.rows <- cbind(c("file1.rda","file2.rda","file3.rda"),c("A","B","C"),c(12,13,14))

for (i in 1:nrow(input.rows)) {
  doQueries(filenameX=input.rows[i,1], inp1=input.rows[i,2], inp2=input.rows[i,3])
}

我已尝试使用以下代码,但 foreach-library 似乎不可用,正如我从阅读 CRAN 中了解到的那样,parallel 正在替换早期的并行包(“包'foreach'不可用(对于 R 版本 2.15. 0)")。

library(parallel)
library(foreach)
foreach (i=1:nrow(input.rows)) %dopar% {
  doQueries(filenameX=input.rows[i,1], inp1=input.rows[i,2], inp2=input.rows[i,3])
}

我应该怎么做呢?

感谢 Stackoverflow 上的所有贡献者!

/克里斯

更新:感谢 nograpes,我设法加载了库。以下代码似乎有效:

library(RODBC)
library(doParallel)
library(foreach)

# odbcCloseAll()
# my_conn <- odbcConnect("database", uid="xx", pwd="yy", case="nochange")

doQueries <- function(filenameX, inp1, inp2) {
  print(paste("Starting:", inp1, inp2, ",saving to", filenameX, sep=" "))
  # sql.test <- RODBC::sqlQuery(my_conn, "SELECT * FROM zzz LIMIT 100", rows_at_time=1024)
  # save(sql.test, file="filenameX")
}

input.rows <- cbind(c("file1.rda","file2.rda","file3.rda"),c("A","B","C"),c(12,13,14))

cl <- makeCluster(3)
registerDoParallel(cl)

foreach (i=1:nrow(input.rows)) %dopar% {
  doQueries(filenameX=input.rows[i,1], inp1=input.rows[i,2], inp2=input.rows[i,3])
}

stopCluster(cl)

但是当我包含实际的 SQL 查询时,会出现此错误消息:{ 中的错误:任务 1 失败 - “第一个参数不是开放的 RODBC 通道”

难道这在概念上不起作用?RODBC 一次不能处理多个查询?

我真的很感谢所有的支持。

/克里斯

更新 2:非常感谢 nograpes 提供的非常好的和令人印象深刻的答案。很难判断数据传输本身是否更快(我认为总吞吐量快 20%),但我发现由于查询(大约 100 个)具有不同的响应时间,并且需要后处理(我将其包含在函数中在保存之前),我可以更好地利用链路和本地 CPU。即,当时只有一个查询,CPU 在数据传输过程中几乎没有使用,然后在 CPU 工作时链接将保持安静。通过并行查询,我看到数据到达并且 CPU 同时工作。总的来说,它变得更快了。非常感谢!

/克里斯

4

1 回答 1

7

正如我在评论中提到的,这种技术可能不会更快。为了回答您的问题,该foreach软件包适用于您的 R 版本。也许您选择的存储库尚未更新。尝试这个:

install.packages('foreach', repos='http://cran.us.r-project.org')

这应该安装软件包。如果这不起作用,请在此处获取您的操作系统的二进制文件,然后通过菜单安装它。

如果瓶颈是网络连接,那么你只能通过减少你放在网络上的东西来加快这个过程。一个想法是远程连接到数据库服务器,让它将查询转储到一个文件(在服务器上),压缩它,然后将它下载到您的计算机,然后让 R 解压缩并加载它。听起来很多,但您可能可以在 R 中完成整个过程。

跟进您的更新,您的陈述中似乎没有包含.packages论点foreach。这就是为什么你必须在sqlQuery函数前面加上RODBC::. 有必要指定循环需要哪些包,因为我认为它本质上为每个节点启动了一个新的 R 会话,并且每个会话都需要使用包进行初始化。同样,您无法访问my_conn,因为它在循环之外,您需要在循环内部创建,以便每个节点都有自己的副本。

library(RODBC)
library(foreach)
library(doParallel)
setwd('C:/Users/x/Desktop')

doQueries <- function(filenameX) {
  sql.text<-sqlQuery(my_conn, 'SELECT * FROM table;')
  save(sql.text, file=filenameX)
}

cl <- makeCluster(2)
registerDoParallel(cl)

foreach (i=1:2, .packages='RODBC') %dopar% {
  my_conn <- odbcConnect("db", uid="user", pwd="pass")
  doQueries(filenameX=paste('file_',i,sep=''))
}

但是,就像我提到的那样,这可能不会更快。

于 2012-05-15T16:15:48.657 回答