我正在尝试使用R从MySQL数据库并行获取数据。以下代码逐个获取数据并正常工作。但我希望通过发送多个查询并将其保存到不同的变量来加快进程。稍后我会在变量中合并时间序列。
library(RMySQL)
dbConnect(MySQL(), user='external', password='xxxxxxx', dbname='GMT_Minute_Data', host='xx.xx.xxx.xxx')
sqlData <-select TradeTime, Open, High, Low, Close from ad where tradetime between ‘2014-01-01’ and ‘2015-10-20’
data1= dbFetch(sqlData, n=-1)
sqlData <-select TradeTime, Open, High, Low, Close from ty where tradetime between ‘2014-01-01’ and ‘2015-10-20’
data2 = dbFetch(sqlData, n=-1)
sqlData <-select TradeTime, Open, High, Low, Close from ax where tradetime between ‘2014-01-01’ and ‘2015-10-20’
data3 = dbFetch(sqlData, n=-1)
connections <- dbListConnections(MySQL())
for(i in connections) {dbDisconnect(i)}
我尝试使用以下代码并行获取数据:
library(foreach)
library(doParallel)
library(RMySQL)
fetchData<- function(nInst, inst1, inst2, inst3, inst4, inst5, startDate, endDate, con1){
inst<-NULL
sqlData <-NULL
if(nInst==1)
inst<-inst1
else if(nInst==2)
inst<-inst2
else if(nInst==3)
inst<-inst3
else if(nInst==4)
inst<-inst4
else if(nInst==5)
inst<-inst5
sqlData <- dbSendQuery(con1, paste0('select TradeTime, Open, High, Low, Close from ', inst, ' where tradetime between \'', startDate, '\' and \'', endDate, '\'' ))
data1 = dbFetch(sqlData, n=-1)
print(head(data1))
data1
}
cluster = makeCluster(5, type = "SOCK")
registerDoParallel(cluster)
mydb <- NULL
clusterEvalQ(cluster, {
mydb <- dbConnect(MySQL(), user='external', password='xxxxxx', dbname='GMT_Minute_Data', host='xx.xx.xxx.xxx')
NULL
})
allDataList<-foreach(n =1:2, .verbose=TRUE, .packages=('RMySQL')) %dopar% {
fetchData(n, inst1, inst2, inst3, inst4, inst5, startDate, endDate, mydb)
}
stopCluster(cluster)
on.exit(dbDisconnect(mydb))
有时代码只提取第一台乐器的数据,而不是其他乐器的数据。
如果有人知道解决方案,请提供帮助。
谢谢,
答案 0 :(得分:0)
我认为问题在于foreach会将mydb
变量自动导出给工作人员,从而无法用clusterEvalQ
初始化它。数据库连接无法序列化并正确发送到其他计算机,这就是使用clusterEvalQ
手动初始化数据库连接的原因。通过foreach .verbose=TRUE
选项,您可以验证mydb
不是否已自动导出。如果它说它是自动导出的,你需要阻止它。
在您的示例中,您可以通过简单地删除mydb
语句来阻止mydb <- NULL
自动导出,但我建议您使用foreach .noexport='mydb'
选项来确定它是从不自动导出。这是一个精简的例子:
library(doParallel)
fetchData <- function(ignore) {
mydb
}
cluster <- makeCluster(5, type = "SOCK")
registerDoParallel(cluster)
clusterEvalQ(cluster, {
mydb <- sample(100, 1) # different value for each worker
NULL
})
r <- foreach(n=1:2, .noexport='mydb', .verbose=TRUE) %dopar% {
fetchData(n)
}
在这种情况下,foreach会分析fetchData
函数并注意到它正在使用名为mydb
的变量。因此,如果在主服务器上定义了mydb
,它将自动导出它,除非您告诉它不要。这就是为什么我建议使用.noexport='mydb'
,即使它没有在本地环境中定义。它确保您的函数不会使用损坏的数据库连接。