Il est plus efficace de créer la connexion à la base de données une fois par travailleur, plutôt qu'une fois par tâche. Malheureusement, mclapply ne fournit pas de mécanisme pour initialiser les travailleurs avant d'exécuter des tâches, il n'est donc pas facile de le faire en utilisant le backend doMC, mais si vous utilisez le backend doParallel, vous pouvez initialiser les travailleurs en utilisant clusterEvalQ. Voici un exemple de restructuration du code :
library(doParallel)
cl <- makePSOCKcluster(detectCores())
registerDoParallel(cl)
clusterEvalQ(cl, {
library(DBI)
library(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, dbname="nsdq")
NULL
})
id.qed.foreach <- foreach(i=1588:3638, .inorder=FALSE,
.noexport="con",
.packages=c("DBI", "RPostgreSQL")) %dopar% {
lst <- eval(expr.01) #contains the SQL query which depends on 'i'
qry <- dbSendQuery(con, lst)
tmp <- fetch(qry, n=-1)
dt <- dates.qed2[i]
list(date=dt, idreuters=tmp$idreuters)
}
clusterEvalQ(cl, {
dbDisconnect(con)
})
Puisque doParallel et clusterEvalQ utilisent le même objet cluster cl
, la boucle foreach aura accès à l'objet de connexion à la base de données con
lors de l'exécution des tâches.