Realizo muchas consultas SQL a una base de datos de la industria muy lejos, pero lleva mucho tiempo recibir los resultados. Fue mucho más rápido cuando mi computadora con R estaba casi al lado de la base de datos, lo que me lleva a pensar que es la latencia entre mi computadora y la base de datos el cuello de botella, y que ejecutar consultas paralelas puede acelerar las cosas. Estamos en diferentes continentesParallel for-loop en Windows
Aquí está una versión de trabajo que no está en paralelo:
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])
}
He tratado con el siguiente código, pero el foreach-biblioteca no parecen estar disponible y como yo entiendo de la lectura en CRAN, paralelo está reemplazando paquetes anteriores por paralelo ("paquete 'foreach' no está disponible (para R versión 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])
}
¿Cómo debo hacer esto?
¡Gracias a todos los colaboradores de Stackoverflow!
/Chris
Actualización: Gracias a nograpes, me las arreglé para cargar las bibliotecas. El siguiente código parece funcionar:
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)
Pero cuando incluyo el SQL-consulta real, aparece este mensaje-error: Error en {: tarea 1 falló - "primer argumento no es un canal RODBC abierta"
¿Podría ser para que esto no funcione conceptualmente? ¿Que RODBC no puede manejar más de una consulta a la vez?
Realmente aprecio todo el apoyo.
/Chris
Actualización 2: Muchas gracias por las respuestas nograpes muy buenas e impresionantes. Es difícil juzgar si las transferencias de datos son más rápidas (creo que el rendimiento total es un 20% más rápido), pero encontré que las consultas (alrededor de 100) tienen diferentes tiempos de respuesta y necesitan un postprocesamiento (que incluyo en la función antes de guardar), obtengo una mejor utilización del enlace y la CPU local. Es decir. con solo una consulta en ese momento, las CPU casi no se utilizarán durante la transferencia de datos, y luego el enlace permanecerá en silencio mientras las CPU funcionen. Con consultas paralelas, veo que llegan datos y que las CPU funcionan al mismo tiempo. En total, se volvió mucho más rápido. ¡Muchas gracias!
/Chris
Si el cuello de botella es la conexión de red entre su computadora y la base de datos, una consulta paralela no será más rápida. Las consultas SQL se ejecutarán simultáneamente en la base de datos (que puede ser un poco más rápido, pero tal vez no), y luego se enviarán a su computadora. El envío a la parte de su computadora será la parte lenta, la cual no cambia en absoluto paralelizándola. – nograpes